1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/jspdf.es.min-CWHF2JOV.js","assets/index-CNT5CkK7.js","assets/index-C8aByjPn.css"])))=>i.map(i=>d[i]); 2import { c as createLucideIcon, k as useAuth, a as useAgentAuth, u as useLocation, r as reactExports, t as trpc, b as toast, j as jsxRuntimeExports, C as CircleAlert, U as USFlag, B as Button, l as Settings, L as LoaderCircle, K as FileSpreadsheet, d as Badge, o as RefreshCw, Z as Bot, F as FileText, E as Eye, g as ChevronRight, aA as __vitePreload, X, a3 as Gift, M as Mail, v as Send, _ as TrendingUp } from './index-CNT5CkK7.js'; 3import { D as DatePicker } from './DatePicker-mymcOl0Q.js'; 4import { A as AgentChat } from './AgentChat-DDAj7r8S.js'; 5import { L as LoginPrompt } from './LoginPrompt-CHjJZnu_.js'; 6import { C as Card, a as CardContent, b as CardHeader, c as CardTitle } from './card-CV3CzesJ.js'; 7import { I as Input } from './input-Dy4-W9m0.js'; 8import { L as Label } from './label-BdZn6Q6n.js'; 9import { T as Tabs, a as TabsList, b as TabsTrigger, c as TabsContent } from './tabs-50Gco_8f.js'; 10import { D as Dialog, a as DialogTrigger, b as DialogContent, c as DialogHeader, d as DialogTitle, k as DialogDescription, e as DialogFooter } from './useComposition-DPCJbBnn.js'; 11import { S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem } from './select-3x7TRCw-.js'; 12import { T as Textarea } from './textarea-B3UNOK9R.js'; 13import { P as Plus } from './plus-BP2QxMPQ.js'; 14import { D as Download } from './download-BMCjKajM.js'; 15import { S as Search } from './search-BQjKKf9D.js'; 16import { U as Upload } from './upload-BrgTKlQs.js'; 17import { C as CircleCheckBig } from './circle-check-big-CmJOxlC9.js'; 18import { T as Trash2 } from './trash-2-DkCMhEWr.js'; 19import { C as CircleCheck } from './circle-check-CqW-unub.js'; 20import { S as Sparkles } from './sparkles-I54sm_K8.js'; 21import { F as FileDown } from './file-down-CrR0CtQE.js'; 22import { C as CirclePlus } from './circle-plus-By14nPvx.js'; 23import { E as ExternalLink } from './external-link-BPkSVFWl.js'; 24import './chevron-down-DFKrqu4j.js'; 25import './calendar-CGh5WTcU.js'; 26import './user-B4RG8T6t.js'; 27import './check-BezXvNsL.js'; 28import './copy-BAoxz8Jl.js'; 29import './index-D1Fi90JZ.js'; 30import './index-BEBgmBqK.js'; 31import './index-B88B3rZe.js'; 32import './chevron-up-Do8Lk9oa.js'; 33 34/** 35 * @license lucide-react v0.453.0 - ISC 36 * 37 * This source code is licensed under the ISC license. 38 * See the LICENSE file in the root directory of this source tree. 39 */ 40 41 42const Calculator = createLucideIcon("Calculator", [ 43 ["rect", { width: "16", height: "20", x: "4", y: "2", rx: "2", key: "1nb95v" }], 44 ["line", { x1: "8", x2: "16", y1: "6", y2: "6", key: "x4nwl0" }], 45 ["line", { x1: "16", x2: "16", y1: "14", y2: "18", key: "wjye3r" }], 46 ["path", { d: "M16 10h.01", key: "1m94wz" }], 47 ["path", { d: "M12 10h.01", key: "1nrarc" }], 48 ["path", { d: "M8 10h.01", key: "19clt8" }], 49 ["path", { d: "M12 14h.01", key: "1etili" }], 50 ["path", { d: "M8 14h.01", key: "6423bh" }], 51 ["path", { d: "M12 18h.01", key: "mhygvu" }], 52 ["path", { d: "M8 18h.01", key: "lrp35t" }] 53]); 54 55/** 56 * @license lucide-react v0.453.0 - ISC 57 * 58 * This source code is licensed under the ISC license. 59 * See the LICENSE file in the root directory of this source tree. 60 */ 61 62 63const CircleMinus = createLucideIcon("CircleMinus", [ 64 ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }], 65 ["path", { d: "M8 12h8", key: "1wcyev" }] 66]); 67 68/** 69 * @license lucide-react v0.453.0 - ISC 70 * 71 * This source code is licensed under the ISC license. 72 * See the LICENSE file in the root directory of this source tree. 73 */ 74 75 76const FilePlus = createLucideIcon("FilePlus", [ 77 ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }], 78 ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }], 79 ["path", { d: "M9 15h6", key: "cctwl0" }], 80 ["path", { d: "M12 18v-6", key: "17g6i2" }] 81]); 82 83/** 84 * @license lucide-react v0.453.0 - ISC 85 * 86 * This source code is licensed under the ISC license. 87 * See the LICENSE file in the root directory of this source tree. 88 */ 89 90 91const Maximize2 = createLucideIcon("Maximize2", [ 92 ["polyline", { points: "15 3 21 3 21 9", key: "mznyad" }], 93 ["polyline", { points: "9 21 3 21 3 15", key: "1avn1i" }], 94 ["line", { x1: "21", x2: "14", y1: "3", y2: "10", key: "ota7mn" }], 95 ["line", { x1: "3", x2: "10", y1: "21", y2: "14", key: "1atl0r" }] 96]); 97 98/** 99 * @license lucide-react v0.453.0 - ISC 100 * 101 * This source code is licensed under the ISC license. 102 * See the LICENSE file in the root directory of this source tree. 103 */ 104 105 106const Merge = createLucideIcon("Merge", [ 107 ["path", { d: "m8 6 4-4 4 4", key: "ybng9g" }], 108 ["path", { d: "M12 2v10.3a4 4 0 0 1-1.172 2.872L4 22", key: "1hyw0i" }], 109 ["path", { d: "m20 22-5-5", key: "1m27yz" }] 110]); 111 112/** 113 * @license lucide-react v0.453.0 - ISC 114 * 115 * This source code is licensed under the ISC license. 116 * See the LICENSE file in the root directory of this source tree. 117 */ 118 119 120const ZoomIn = createLucideIcon("ZoomIn", [ 121 ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }], 122 ["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65", key: "13gj7c" }
122], 123 ["line", { x1: "11", x2: "11", y1: "8", y2: "14", key: "1vmskp" }], 124 ["line", { x1: "8", x2: "14", y1: "11", y2: "11", key: "durymu" }] 125]); 126 127/** 128 * @license lucide-react v0.453.0 - ISC 129 * 130 * This source code is licensed under the ISC license. 131 * See the LICENSE file in the root directory of this source tree. 132 */ 133 134 135const ZoomOut = createLucideIcon("ZoomOut", [ 136 ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }], 137 ["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65", key: "13gj7c" }], 138 ["line", { x1: "8", x2: "14", y1: "11", y2: "11", key: "durymu" }] 139]); 140 141const CARRIERS = ["PRG", "Travelers", "Celina", "Nationwide", "Safeco", "Hanover"]; 142const AGENT_SPLIT_RULES = [ 143 { id: "hinkle-josh", name: "Josh Hinkle", key: "Hinkle, Josh", standard: 0.9, master: 1, note: "+10% of Zach's regular carrier commissions only; excludes renewal-processing pay and bonuses" }, 144 { id: "drain-charlie", name: "Charlie Drain", key: "Drain, Charlie", standard: 0.7, master: 0.8, note: "" }, 145 { id: "jividen-michael", name: "Michael Jividen", key: "Jividen, Michael", standard: 0.7, master: 0.8, note: "" }, 146 { id: "bucher-jon", name: "Jon Bucher", key: "Bucher, Jon", standard: 0.7, master: 0.8, note: "" }, 147 { id: "kaufman-adam", name: "Adam Kaufman", key: "Kaufman, Adam", standard: 0.7, master: 0.8, note: "" }, 148 { id: "hinkle-zach", name: "Zach Hinkle", key: "Hinkle, Zach", standard: 0.8, master: 0.8, note: "10% of regular carrier commissions goes to Josh; renewal-processing pay and bonuses are excluded" } 149]; 150const SUB_AGENTS = [ 151 { id: "bucher-jon", name: "Jon Bucher", key: "Bucher, Jon", splitPct: 0.7 }, 152 { id: "jividen-michael", name: "Michael Jividen", key: "Jividen, Michael", splitPct: 0.7 }, 153 { id: "hinkle-josh", name: "Josh Hinkle", key: "Hinkle, Josh", splitPct: 0.9 }, 154 { id: "drain-charlie", name: "Charlie Drain", key: "Drain, Charlie", splitPct: 0.7 }, 155 { id: "kaufman-adam", name: "Adam Kaufman", key: "Kaufman, Adam", splitPct: 0.7 }, 156 { id: "hinkle-zach", name: "Zach Hinkle", key: "Hinkle, Zach", splitPct: 0.8 } 157]; 158const STATUS_CONFIG = { 159 uploaded: { label: "Uploaded", color: "bg-blue-100 text-blue-800", icon: Upload }, 160 processing: { label: "Processing", color: "bg-yellow-100 text-yellow-800", icon: RefreshCw }, 161 calculated: { label: "Calculated", color: "bg-purple-100 text-purple-800", icon: Calculator }, 162 reported: { label: "Reported", color: "bg-green-100 text-green-800", icon: CircleCheckBig } 163}; 164function fmtCurrency(val) { 165 const n = parseFloat(String(val ?? "0")); 166 return isNaN(n) ? "$0.00" : `$${n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; 167} 168function fmtPct(val) { 169 const n = parseFloat(String(val ?? "0")); 170 return isNaN(n) ? "0%" : `${(n * 100).toFixed(0)}%`; 171} 172function fmtRatePct(val) { 173 if (val === null || val === void 0 || val === "") return "â"; 174 const n = Number(val); 175 if (!Number.isFinite(n)) return "â"; 176 return `${(n * 100).toFixed(2).replace(/\.00$/, "")}%`; 177} 178const DEFAULT_PERFORMANCE_BONUS_TRACKERS = [ 179 { 180 carrier: "Progressive Insurance", 181 title: "2026 Personal Lines Performance Bonus", 182 asOf: "As of June 30, 2026", 183 description: "Personal-lines PIF growth, CAT-adjusted loss ratio, bonus path, and agency kicker tracker.", 184 imageUrl: "/manus-storage/progressive_2026_performance_bonus_8ec5f91c.png", 185 accent: "border-[#0b4da2]", 186 badge: "bg-[#0b4da2]" 187 }, 188 { 189 carrier: "Hanover", 190 title: "2026 Personal Lines Profit Sharing", 191 asOf: "June 2026 projected status", 192 description: "Written-premium growth, loss-ratio thresholds, projected bonus tiers, and combined strategy matrix.", 193 imageUrl: "/manus-storage/hanover_2026_profit_sharing_079bdf1c.png", 194 accent: "border-[#522071]", 195 badge: "bg-[#522071]" 196 }, 197 { 198 carrier: "Celina Insurance Group", 199 title: "2026 Growth & Profit Incentive", 200 asOf: "July 2026 YTD working estimate", 201 description: "Written-premium pace, growth-bonus thresholds, loss-ratio qualification, and incentive outlook.", 202 imageUrl: "/manus-storage/celina_2026_growth_profit_incentive_030464e6.png", 203 accent: "border-[#2e7d32]", 204 badge: "bg-[#2e7d32]" 205 } 206]; 207function PerformanceBonusTrackers({ isAdmin }) { 208 const utils = trpc.useUtils(); 209 const trackerQuery = trpc.performanceBonusTrackers.list.useQuery(); 210 const [editorOpen, setEditorOpen] = reactExports.useState(false); 211 const [editingTracker, setEditingTracker] = reactExports.useState(null); 212 const [draftTitle, setDraftTitle] = reactExports.useState(""); 213 const [draftAsOf, setDraftAsOf] = reactExports.useState(""); 214 const [draftDescription, setDraftDescription] = reactExports.useState(""); 215 const [uploadedImage, setUploadedImage] = reactExports.useState(null); 216 const [viewingTracker, setViewingTracker] = reactExports.useState(null); 217 const [trackerZoom, setTrackerZoom] = reactExports.useState(1); 218 const trackers = trackerQuery.data?.length ? trackerQuery.data.map((tracker) => ({ 219 id: tracker.id, 220 carrier: tracker.carrier, 221 title: tracker.title, 222 asOf: tracker.asOf, 223 description: tracker.description, 224 imageUrl: tracker.imageUrl, 225 accent: tracker.accent, 226 badge: tracker.badge 227 })) : DEFAULT_PERFORMANCE_BONUS_TRACKERS; 228 const publishMutation = trpc.performanceBonusTrackers.publish.useMutation({ 229 onSuccess: async (data) => {
230 await utils.performanceBonusTrackers.list.invalidate(); 231 setEditorOpen(false); 232 setUploadedImage(null); 233 toast.success(`Published ${data.tracker.carrier}; ${data.recipientsNotified} producer update${data.recipientsNotified === 1 ? "" : "s"} sent.`); 234 if (data.notificationFailures) toast.warning(`${data.notificationFailures} producer notification${data.notificationFailures === 1 ? "" : "s"} could not be delivered.`); 235 }, 236 onError: (error) => toast.error(error.message || "Tracker update could not be published") 237 }); 238 function openEditor(tracker) { 239 setEditingTracker(tracker); 240 setDraftTitle(tracker.title); 241 setDraftAsOf(tracker.asOf); 242 setDraftDescription(tracker.description); 243 setUploadedImage(null); 244 setEditorOpen(true); 245 } 246 function openTrackerViewer(tracker) { 247 setViewingTracker(tracker); 248 setTrackerZoom(1); 249 } 250 async function chooseImage(file) { 251 if (!file) return; 252 if (!["image/png", "image/jpeg", "image/webp"].includes(file.type)) { 253 toast.error("Use a PNG, JPG, or WebP tracker image."); 254 return; 255 } 256 if (file.size > 5 * 1024 * 1024) { 257 toast.error("Tracker images must be 5 MB or smaller."); 258 return; 259 } 260 const dataUrl = await new Promise((resolve, reject) => { 261 const reader = new FileReader(); 262 reader.onload = () => resolve(String(reader.result)); 263 reader.onerror = () => reject(new Error("The tracker image could not be read")); 264 reader.readAsDataURL(file); 265 }); 266 setUploadedImage({ 267 base64: dataUrl.split(",")[1] ?? "", 268 mimeType: file.type, 269 fileName: file.name 270 }); 271 } 272 function publishUpdate() { 273 if (!editingTracker) return; 274 publishMutation.mutate({ 275 carrier: editingTracker.carrier, 276 title: draftTitle, 277 asOf: draftAsOf, 278 description: draftDescription, 279 imageBase64: uploadedImage?.base64, 280 imageMimeType: uploadedImage?.mimeType, 281 fileName: uploadedImage?.fileName 282 }); 283 } 284 return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { "aria-labelledby": "performance-bonuses-heading", children: [ 285 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border-2 border-[#3C3B6E]/30", children: [
286 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { className: "pb-3 bg-[#3C3B6E]/5 border-b border-[#3C3B6E]/15", children: [ 287 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { id: "performance-bonuses-heading", className: "text-base text-[#3C3B6E] flex items-center gap-2", children: [ 288 /* @__PURE__ */ jsxRuntimeExports.jsx(Gift, { className: "w-5 h-5 text-[#B22234]" }), 289 " Performance Bonuses & Profit Sharing" 290 ] }), 291 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600", children: "Carrier-specific bonus and profit-sharing trackers. These are separate from monthly commission statements and show the latest supplied planning status." }) 292 ] }), 293 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "pt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid gap-4 xl:grid-cols-3", children: trackers.map((tracker) => /* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: `flex flex-col min-w-0 rounded-lg border ${tracker.accent} bg-white overflow-hidden`, children: [
294 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 pb-3", children: [ 295 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [ 296 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ 297 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-gray-500", children: tracker.carrier }), 298 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "mt-1 text-sm font-bold text-[#3C3B6E]", children: tracker.title }) 299 ] }), 300 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `${tracker.badge} shrink-0 rounded-full px-2 py-1 text-[10px] font-semibold text-white`, children: "Tracker" }) 301 ] }), 302 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs font-medium text-gray-600", children: tracker.asOf }) 303 ] }), 304 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-4 flex items-center justify-center rounded-md border border-gray-200 bg-slate-950 h-[230px] overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx( 305 "img", 306 { 307 src: tracker.imageUrl, 308 alt: `${tracker.carrier} ${tracker.title} tracker`, 309 className: "h-full w-full object-contain" 310 } 311 ) }),
312 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col p-4 pt-3", children: [ 313 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs leading-relaxed text-gray-600", children: tracker.description }), 314 /* @__PURE__ */ jsxRuntimeExports.jsxs( 315 Button, 316 { 317 variant: "outline", 318 size: "sm", 319 className: "mt-4 w-full gap-1.5 border-[#3C3B6E]/35 text-[#3C3B6E]", 320 onClick: () => openTrackerViewer(tracker), 321 children: [ 322 /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-3.5 h-3.5" }), 323 " View Full Tracker" 324 ] 325 } 326 ), 327 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs( 328 Button, 329 { 330 variant: "outline", 331 size: "sm", 332 className: "mt-2 w-full gap-1.5 border-[#B22234]/35 text-[#B22234]", 333 onClick: () => openEditor(tracker), 334 children: [
335 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-3.5 h-3.5" }), 336 " Update & Notify Producers" 337 ] 338 } 339 ) 340 ] }) 341 ] }, tracker.carrier)) }) }) 342 ] }), 343 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: !!viewingTracker, onOpenChange: (open) => { 344 if (!open) { 345 setViewingTracker(null); 346 setTrackerZoom(1); 347 } 348 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogContent, { className: "flex h-[96vh] w-[98vw] max-w-none flex-col overflow-hidden p-0 sm:max-w-none", children: viewingTracker && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 349 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { className: "shrink-0 border-b border-slate-200 bg-white px-5 py-4 pr-14 text-left", children: [ 350 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-base text-[#3C3B6E] sm:text-lg", children: [ 351 viewingTracker.carrier, 352 " â ", 353 viewingTracker.title 354 ] }),
355 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogDescription, { className: "mt-1 text-xs sm:text-sm", children: [ 356 viewingTracker.asOf, 357 ". Use the controls below to enlarge the tracker or open its original size." 358 ] }), 359 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [ 360 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", onClick: () => setTrackerZoom((current) => Math.max(0.8, Number((current - 0.2).toFixed(1)))), disabled: trackerZoom <= 0.8, children: [ 361 /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomOut, { className: "mr-1.5 h-3.5 w-3.5" }), 362 " Zoom out" 363 ] }), 364 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-14 text-center text-xs font-semibold text-slate-600", children: [ 365 Math.round(trackerZoom * 100), 366 "%" 367 ] }), 368 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", onClick: () => setTrackerZoom((current) => Math.min(2.5, Number((current + 0.2).toFixed(1)))), disabled: trackerZoom >= 2.5, children: [
369 /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomIn, { className: "mr-1.5 h-3.5 w-3.5" }), 370 " Zoom in" 371 ] }), 372 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", onClick: () => setTrackerZoom(1), disabled: trackerZoom === 1, children: "Reset" }), 373 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { asChild: true, variant: "outline", size: "sm", className: "ml-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("a", { href: viewingTracker.imageUrl, target: "_blank", rel: "noreferrer", children: [ 374 /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "mr-1.5 h-3.5 w-3.5" }), 375 " Open original" 376 ] }) }) 377 ] }) 378 ] }), 379 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 flex-1 overflow-auto bg-slate-950 p-3 sm:p-5", children: /* @__PURE__ */ jsxRuntimeExports.jsx( 380 "img", 381 { 382 src: viewingTracker.imageUrl, 383 alt: `${viewingTracker.carrier} ${viewingTracker.title} full tracker`, 384 style: { width: `${trackerZoom * 100}%` }, 385 className: "mx-auto block h-auto min-w-[720px] max-w-none rounded-sm bg-white" 386 } 387 ) }) 388 ] }) }) }), 389 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: editorOpen, onOpenChange: setEditorOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "sm:max-w-xl", children: [
390 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 391 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Publish Tracker Update" }), 392 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Publishing replaces the selected tracker and immediately emails all active producers. Ryan Fay is excluded." }) 393 ] }), 394 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 py-2", children: [ 395 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 396 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { children: "Carrier" }), 397 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { value: editingTracker?.carrier ?? "", disabled: true }) 398 ] }), 399 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 400 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "tracker-title", children: "Tracker title" }), 401 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { id: "tracker-title", value: draftTitle, onChange: (event) => setDraftTitle(event.target.value) }) 402 ] }),
403 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 404 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "tracker-as-of", children: "As-of date or status" }), 405 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { id: "tracker-as-of", value: draftAsOf, onChange: (event) => setDraftAsOf(event.target.value), placeholder: "As of August 31, 2026" }) 406 ] }), 407 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 408 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "tracker-description", children: "Producer-facing summary" }), 409 /* @__PURE__ */ jsxRuntimeExports.jsx(Textarea, { id: "tracker-description", value: draftDescription, onChange: (event) => setDraftDescription(event.target.value), rows: 4 }) 410 ] }), 411 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 412 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "tracker-image", children: "Replacement tracker image (optional)" }),
413 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { id: "tracker-image", type: "file", accept: "image/png,image/jpeg,image/webp", onChange: (event) => void chooseImage(event.target.files?.[0]) }), 414 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "PNG, JPG, or WebP; 5 MB maximum. Leave blank to retain the current image." }), 415 uploadedImage && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-medium text-[#2e7d32]", children: [ 416 "Ready to publish: ", 417 uploadedImage.fileName 418 ] }) 419 ] }) 420 ] }), 421 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 422 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setEditorOpen(false), disabled: publishMutation.isPending, children: "Cancel" }), 423 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: publishUpdate, disabled: publishMutation.isPending || !draftTitle.trim() || !draftAsOf.trim() || draftDescription.trim().length < 10, children: [
424 publishMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 mr-2 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4 mr-2" }), 425 " Publish & Notify Producers" 426 ] }) 427 ] }) 428 ] }) }) 429 ] }); 430} 431const REQUIRED_FIELDS = [ 432 { key: "accountName", label: "Account / Insured Name", required: true, hint: 'e.g. "Insured", "Client", "Account Name"' }, 433 { key: "commissionEarned", label: "Commission Earned ($)", required: false, hint: "Map this, or map Premium + Commission Rate" }, 434 { key: "assignedAgentKey", label: "Agent / Producer", required: true, hint: 'e.g. "Producer", "Agent", "Sub Agent"' }, 435 { key: "policyNumber", label: "Policy Number", required: false, hint: 'e.g. "Policy #", "Policy No"' }, 436 { key: "carrier", label: "Carrier", required: false, hint: 'e.g. "Company", "Carrier"' }, 437 { key: "lineOfBusiness", label: "Line of Business", required: false, hint: 'e.g. "LOB", "Line"' }, 438 { key: "transactionType", label: "Transaction Type", required: false, hint: 'e.g. "Type", "Trans Type"' }, 439 { key: "premium", label: "Premium ($)", required: false, hint: 'e.g. "Written Premium", "Amount"' }, 440 { key: "commissionRate", label: "Commission Rate (%)", required: false, hint: 'e.g. "Comm %", "Rate"' }, 441 { key: "effectiveDate", label: "Effective Date", required: false, hint: 'e.g. "Eff Date", "Date"' }, 442 { key: "notes", label: "Notes / Comments", required: false, hint: 'e.g. "Remarks", "Notes"' } 443]; 444function autoGuessMapping(headers) { 445 const norm = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, ""); 446 const guess = {}; 447 const GUESSES = { 448 accountName: ["accountname", "insured", "client", "name", "account"], 449 commissionEarned: ["commissionearned", "netcommission", "commamount", "earned", "commission"], 450 assignedAgentKey: ["agent", "producer", "subagent", "agentid", "agentname"], 451 policyNumber: ["policynumber", "policy", "policyno"], 452 carrier: ["carrier", "company", "insurancecompany"], 453 lineOfBusiness: ["lineofbusiness", "lob", "line", "coverage"], 454 transactionType: ["transactiontype", "type", "transtype", "description"], 455 premium: ["premium", "writtenpremium", "grosspremium", "amount"], 456 commissionRate: ["commissionrate", "rate", "commrate", "comm"], 457 effectiveDate: ["effectivedate", "effdate", "date", "policydate"], 458 notes: ["notes", "comments", "remarks"] 459 }; 460 for (const [field, candidates] of Object.entries(GUESSES)) { 461 const match = headers.find((h) => candidates.includes(norm(h))); 462 if (match) guess[field] = match; 463 } 464 return guess; 465} 466function UploadStatementModal({ 467 onSuccess, 468 initialPeriod, 469 forceOpen, 470 onForceOpenChange 471}) { 472 const isControlled = forceOpen !== void 0; 473 const [open, setOpen] = reactExports.useState(false); 474 const effectiveOpen = isControlled ? forceOpen : open; 475 const setEffectiveOpen = (v) => { 476 if (isControlled) onForceOpenChange?.(v); 477 else setOpen(v); 478 }; 479 const [step, setStep] = reactExports.useState("form"); 480 const [period, setPeriod] = reactExports.useState(initialPeriod ?? ""); 481 const [carrier, setCarrier] = reactExports.useState(""); 482 const [dragging, setDragging] = reactExports.useState(false); 483 const [uploading, setUploading] = reactExports.useState(false); 484 const [pendingFile, setPendingFile] = reactExports.useState(null); 485 const [spreadsheetHeaders, setSpreadsheetHeaders] = reactExports.useState([]); 486 const [columnMap, setColumnMap] = reactExports.useState({}); 487 const [result, setResult] = reactExports.useState(null); 488 const fileInputRef = reactExports.useRef(null); 489 const [existingPeriodInfo, setExistingPeriodInfo] = reactExports.useState(null); 490 const STORAGE_KEY = (c) => `eps_col_map_${c.toLowerCase().replace(/\s+/g, "_")}`; 491 const loadSavedMapping = (c) => { 492 try { 493 const v = localStorage.getItem(STORAGE_KEY(c)); 494 return v ? JSON.parse(v) : null; 495 } catch { 496 return null; 497 } 498 }; 499 const saveMapping = (c, map) => { 500 try { 501 localStorage.setItem(STORAGE_KEY(c), JSON.stringify(map)); 502 } catch { 503 } 504 }; 505 const handleFile = reactExports.useCallback(async (file) => { 506 if (!period) {
507 toast.error("Please enter the period (e.g. 2026-04) before uploading"); 508 return; 509 } 510 const ext = file.name.split(".").pop()?.toLowerCase(); 511 if (!ext || !["xlsx", "xls", "csv"].includes(ext)) { 512 toast.error("Please upload an Excel (.xlsx/.xls) or CSV file"); 513 return; 514 } 515 try { 516 const buf = await file.arrayBuffer(); 517 const XLSX = await __vitePreload(() => import('./xlsx-yBJAythd.js'),true ?[]:void 0); 518 const wb = XLSX.read(buf, { type: "array" }); 519 const ws = wb.Sheets[wb.SheetNames[0]]; 520 const rows = XLSX.utils.sheet_to_json(ws, { header: 1, defval: "" }); 521 const headers = rows[0].map(String).filter(Boolean); 522 setSpreadsheetHeaders(headers); 523 const saved = carrier ? loadSavedMapping(carrier) : null; 524 const guessedMapping = saved ?? autoGuessMapping(headers); 525 if (guessedMapping.commissionEarned && guessedMapping.commissionEarned === guessedMapping.commissionRate) { 526 guessedMapping.commissionEarned = ""; 527 } 528 setColumnMap(guessedMapping); 529 setPendingFile(file); 530 if (initialPeriod) { 531 setStep("mapping"); 532 return; 533 } 534 try { 535 const checkRes = await fetch(`/api/upload/commissions-check-period?period=${encodeURIComponent(period)}`); 536 if (checkRes.ok) { 537 const checkData = await checkRes.json(); 538 if (checkData.exists && checkData.statementId) { 539 setExistingPeriodInfo({ 540 statementId: checkData.statementId, 541 period: checkData.period ?? period, 542 carrier: checkData.carrier ?? null, 543 status: checkData.status ?? "uploaded", 544 totalEarned: checkData.totalEarned ?? "0", 545 fileCount: checkData.fileCount ?? 0, 546 totalTransactions: checkData.totalTransactions ?? 0, 547 downloadedFileCount: checkData.downloadedFileCount ?? 0, 548 manualFileCount: checkData.manualFileCount ?? 0, 549 downloadedSubtotal: checkData.downloadedSubtotal ?? "0", 550 manualSubtotal: checkData.manualSubtotal ?? "0" 551 }); 552 setStep("mapping"); 553 return; 554 } 555 } 556 } catch { 557 } 558 setStep("mapping"); 559 } catch { 560 toast.error("Could not read spreadsheet headers. Please check the file format."); 561 } 562 }, [period, carrier]); 563 const hasRequiredMapping = Boolean( 564 columnMap.accountName && columnMap.assignedAgentKey && (columnMap.commissionEarned || columnMap.premium && columnMap.commissionRate) 565 ); 566 const handleUpload = reactExports.useCallback(async () => { 567 if (!pendingFile) return; 568 setUploading(true); 569 try { 570 const fd = new FormData(); 571 fd.append("file", pendingFile); 572 fd.append("period", period); 573 fd.append("carrier", carrier); 574 fd.append("sourceCategory", carrier === "Manually Added Carriers" ? "manual" : "downloaded"); 575 fd.append("isManual", carrier === "Manually Added Carriers" ? "true" : "false"); 576 fd.append("uploadedBy", "agent"); 577 fd.append("columnMap", JSON.stringify(columnMap)); 578 const res = await fetch("/api/upload/commissions-excel", { method: "POST", body: fd }); 579 let json;
580 try { 581 json = await res.json(); 582 } catch { 583 throw new Error(`Server error (${res.status}): unexpected response format`); 584 } 585 if (!res.ok) throw new Error(json.error || "Upload failed"); 586 const uploadResult = json; 587 if (carrier) saveMapping(carrier, columnMap); 588 setResult(uploadResult); 589 setStep("result"); 590 toast.success(`Imported ${uploadResult.activeRowCount} active transactions · Combined total: $${parseFloat(uploadResult.totalEarned).toLocaleString()}`); 591 } catch (err) { 592 toast.error(err instanceof Error ? err.message : "Upload failed"); 593 } finally { 594 setUploading(false); 595 } 596 }, [pendingFile, period, carrier, columnMap]); 597 const handleDrop = reactExports.useCallback((e) => { 598 e.preventDefault(); 599 setDragging(false); 600 const file = e.dataTransfer.files[0]; 601 if (file) handleFile(file); 602 }, [handleFile]); 603 const handleReset = () => { 604 setEffectiveOpen(false); 605 setStep("form"); 606 setResult(null); 607 setPeriod(initialPeriod ?? ""); 608 setCarrier(""); 609 setPendingFile(null); 610 setSpreadsheetHeaders([]); 611 setColumnMap({}); 612 setExistingPeriodInfo(null); 613 }; 614 const handleDone = () => { 615 handleReset(); 616 onSuccess(); 617 }; 618 const NONE_VALUE = "__none__"; 619 return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open: effectiveOpen, onOpenChange: (v) => { 620 if (!v) handleReset(); 621 else setEffectiveOpen(true); 622 }, children: [
623 !isControlled && /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { className: "bg-[#B22234] hover:bg-[#b8973e] text-white gap-2", onClick: () => setEffectiveOpen(true), children: [ 624 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4" }), 625 " Upload Statement" 626 ] }) }), 627 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [ 628 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-[#3C3B6E]", children: [ 629 step === "form" && (initialPeriod ? `Add File to ${initialPeriod} Statement` : "Upload Commission Statement"), 630 step === "mapping" && (initialPeriod ? `Map Columns â Adding to ${initialPeriod}` : "Map Spreadsheet Columns"), 631 step === "result" && "Import Complete" 632 ] }) }), 633 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 text-xs text-gray-400 mb-1", children: ["1. File & Period", "2. Map Columns", "3. Done"].map((label, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `px-2 py-0.5 rounded-full ${step === "form" && i === 0 || step === "mapping" && i === 1 || step === "result" && i === 2 ? "bg-[#3C3B6E] text-white font-medium" : "bg-gray-100"}`, children: label }, i)) }),
634 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 pt-1", children: [ 635 step === "form" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 636 initialPeriod && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 bg-[#3C3B6E]/5 border border-[#3C3B6E]/20 rounded-lg text-sm", children: [ 637 /* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, { className: "w-4 h-4 text-[#3C3B6E] shrink-0" }), 638 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 639 "Adding a new carrier file to statement period ", 640 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-semibold text-[#3C3B6E]", children: initialPeriod }), 641 ". Transactions will be merged into the existing statement." 642 ] }) 643 ] }), 644 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [ 645 !initialPeriod && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
646 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { children: "Period (YYYY-MM) *" }), 647 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { placeholder: "2026-04", value: period, onChange: (e) => setPeriod(e.target.value) }) 648 ] }), 649 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: initialPeriod ? "col-span-2" : "", children: [ 650 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { children: "Source Category *" }), 651 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: carrier, onValueChange: setCarrier, children: [ 652 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select source category" }) }), 653 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 654 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "Downloaded Carriers", children: "Downloaded Carrier Statements" }), 655 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "Manually Added Carriers", children: "Manually Entered Commissions" }) 656 ] }) 657 ] }) 658 ] }) 659 ] }),
660 /* @__PURE__ */ jsxRuntimeExports.jsxs( 661 "div", 662 { 663 className: `border-2 border-dashed rounded-xl p-8 text-center transition-colors cursor-pointer ${dragging ? "border-[#3C3B6E] bg-blue-50" : "border-gray-300 hover:border-[#3C3B6E]/50"}`, 664 onDragOver: (e) => { 665 e.preventDefault(); 666 setDragging(true); 667 }, 668 onDragLeave: () => setDragging(false), 669 onDrop: handleDrop, 670 onClick: () => fileInputRef.current?.click(), 671 children: [ 672 /* @__PURE__ */ jsxRuntimeExports.jsx( 673 "input", 674 { 675 ref: fileInputRef, 676 type: "file", 677 className: "hidden", 678 accept: ".xlsx,.xls,.csv", 679 onChange: (e) => { 680 const f = e.target.files?.[0]; 681 if (f) handleFile(f); 682 } 683 } 684 ),
685 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-2", children: [ 686 /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-10 h-10 text-gray-300" }), 687 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-sm", children: "Drop your commission spreadsheet here" }), 688 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400", children: "Supports .xlsx, .xls, .csv â you'll map columns next" }), 689 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", className: "mt-2", onClick: (e) => { 690 e.stopPropagation(); 691 fileInputRef.current?.click(); 692 }, children: [ 693 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-3.5 h-3.5 mr-1.5" }), 694 " Browse File" 695 ] }) 696 ] }) 697 ] 698 } 699 ) 700 ] }), 701 step === "mapping" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
702 existingPeriodInfo && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border border-[#3C3B6E]/20 bg-[#3C3B6E]/5 p-3 text-xs text-[#3C3B6E]", children: [ 703 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-semibold", children: [ 704 "Adding to the existing unified ", 705 existingPeriodInfo.period, 706 " statement" 707 ] }), 708 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1", children: [ 709 "Downloaded: ", 710 existingPeriodInfo.downloadedFileCount, 711 " file", 712 existingPeriodInfo.downloadedFileCount === 1 ? "" : "s", 713 " / $", 714 parseFloat(existingPeriodInfo.downloadedSubtotal).toLocaleString("en-US", { minimumFractionDigits: 2 }), 715 " · Manual: ", 716 existingPeriodInfo.manualFileCount, 717 " file", 718 existingPeriodInfo.manualFileCount === 1 ? "" : "s", 719 " / $", 720 parseFloat(existingPeriodInfo.manualSubtotal).toLocaleString("en-US", { minimumFractionDigits: 2 }) 721 ] }) 722 ] }),
723 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-gray-600 bg-blue-50 border border-blue-200 rounded-lg p-3", children: [ 724 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [ 725 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 726 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-[#3C3B6E]", children: pendingFile?.name }), 727 " â ", 728 spreadsheetHeaders.length, 729 " columns detected." 730 ] }), 731 carrier && loadSavedMapping(carrier) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs bg-green-100 text-green-700 border border-green-300 rounded px-2 py-0.5", children: [ 732 "â Saved mapping loaded for ", 733 carrier 734 ] }) 735 ] }), 736 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1", children: "Match each field to the correct column in your spreadsheet. Mapping is saved per carrier." }) 737 ] }),
738 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 max-h-[380px] overflow-y-auto pr-1", children: REQUIRED_FIELDS.map((field) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[180px_1fr] items-center gap-3", children: [ 739 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 740 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-[#3C3B6E]", children: [ 741 field.label, 742 field.required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }) 743 ] }), 744 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400", children: field.hint }) 745 ] }), 746 /* @__PURE__ */ jsxRuntimeExports.jsxs( 747 Select, 748 { 749 value: columnMap[field.key] || NONE_VALUE, 750 onValueChange: (v) => setColumnMap((prev) => ({ ...prev, [field.key]: v === NONE_VALUE ? "" : v })), 751 children: [
752 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: `text-sm ${field.required && !columnMap[field.key] ? "border-red-300 bg-red-50" : ""}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "â skip â" }) }), 753 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 754 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: NONE_VALUE, children: "â skip â" }), 755 spreadsheetHeaders.map((h) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: h, children: h }, h)) 756 ] }) 757 ] 758 } 759 ) 760 ] }, field.key)) }), 761 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-1", children: [ 762 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setStep("form"), className: "flex-1", children: "â Back" }), 763 /* @__PURE__ */ jsxRuntimeExports.jsx( 764 Button, 765 { 766 onClick: handleUpload, 767 disabled: uploading || !carrier || !hasRequiredMapping, 768 className: "flex-1 bg-[#3C3B6E] hover:bg-[#3C3B6E] text-white",
769 children: uploading ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 770 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 mr-2 animate-spin" }), 771 " Importing..." 772 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 773 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4 mr-2" }), 774 " Import Statement" 775 ] }) 776 } 777 ) 778 ] }), 779 (!carrier || !hasRequiredMapping) && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-500 text-center", children: "Select a source category and map Account, Agent, plus either Commission Earned or Premium + Commission Rate." }) 780 ] }), 781 step === "result" && result && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 782 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 p-3 bg-green-50 rounded-lg border border-green-200", children: [
783 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "w-5 h-5 text-green-600 shrink-0" }), 784 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 785 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-medium text-sm text-green-800", children: [ 786 result.activeRowCount, 787 " active ", 788 result.sourceCategory, 789 " transactions imported · unified splits recalculated" 790 ] }), 791 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-green-600", children: [ 792 "Source subtotal: $", 793 parseFloat(result.sourceSubtotal).toLocaleString("en-US", { minimumFractionDigits: 2 }) 794 ] }) 795 ] }) 796 ] }), 797 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2 text-xs sm:grid-cols-4", children: [ 798 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border bg-white p-2", children: [
799 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Downloaded" }), 800 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-semibold", children: [ 801 "$", 802 parseFloat(result.downloadedSubtotal).toLocaleString("en-US", { minimumFractionDigits: 2 }) 803 ] }) 804 ] }), 805 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border bg-white p-2", children: [ 806 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Manual" }), 807 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-semibold", children: [ 808 "$", 809 parseFloat(result.manualSubtotal).toLocaleString("en-US", { minimumFractionDigits: 2 }) 810 ] }) 811 ] }), 812 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border bg-white p-2", children: [ 813 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Duplicates excluded" }),
814 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold", children: result.duplicateCount }) 815 ] }), 816 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border bg-white p-2", children: [ 817 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Combined earned" }), 818 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-semibold", children: [ 819 "$", 820 parseFloat(result.totalEarned).toLocaleString("en-US", { minimumFractionDigits: 2 }) 821 ] }) 822 ] }) 823 ] }), 824 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500", children: [ 825 "Producer notifications: ", 826 result.notificationGroupsSent, 827 " agency groups sent", 828 result.notificationGroupsFailed ? ` · ${result.notificationGroupsFailed} failed` : "", 829 "." 830 ] }), 831 result.rows.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-x-auto rounded-lg border", children: [
832 /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [ 833 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-[#3C3B6E] text-white", children: /* @__PURE__ */ jsxRuntimeExports.jsx("tr", { children: ["Account", "Policy #", "LOB", "Type", "Premium", "Comm %", "Earned"].map((h) => /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: h }, h)) }) }), 834 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: result.rows.map((r, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-gray-100", children: [ 835 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 font-medium", children: r.accountName || "â" }), 836 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: r.policyNumber || "â" }), 837 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: r.lineOfBusiness || "â" }), 838 /* @__P
838URE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: r.transactionType || "â" }), 839 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-2", children: [ 840 "$", 841 parseFloat(r.premium || "0").toLocaleString() 842 ] }), 843 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-2", children: [ 844 (parseFloat(r.commissionRate || "0") * 100).toFixed(1), 845 "%" 846 ] }), 847 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-2 font-semibold text-green-700", children: [ 848 "$", 849 parseFloat(r.commissionEarned || "0").toLocaleString() 850 ] }) 851 ] }, i)) }) 852 ] }), 853 result.rowCount > 10 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-400 p-2 text-center", children: [ 854 "Showing first 10 of ", 855 result.rowCount, 856 " rows" 857 ] }) 858 ] }),
859 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: handleDone, className: "w-full bg-[#3C3B6E] hover:bg-[#3C3B6E] text-white", children: [ 860 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "w-4 h-4 mr-2" }), 861 " Done â View Statement" 862 ] }) 863 ] }) 864 ] }) 865 ] }) 866 ] }); 867} 868function AddTransactionsModal({ statementId, period, onSuccess, triggerLabel }) { 869 const [open, setOpen] = reactExports.useState(false); 870 const [rows, setRows] = reactExports.useState([ 871 { accountName: "", policyNumber: "", carrier: "", lineOfBusiness: "", transactionType: "Renewal", commissionEarned: "", assignedAgentKey: "", isDuplicate: false, isAdjustment: false } 872 ]); 873 const addTxns = trpc.commissions.addTransactions.useMutation({ 874 onSuccess: (d) => { 875 toast.success(`${d.count} transactions added`); 876 setOpen(false); 877 onSuccess(); 878 }, 879 onError: (e) => toast.error(e.message) 880 }); 881 const addRow = () => setRows((r) => [...r, { accountName: "", policyNumber: "", carrier: "", lineOfBusiness: "", transactionType: "Renewal", commissionEarned: "", assignedAgentKey: "", isDuplicate: false, isAdjustment: false }]); 882 const updateRow = (i, field, value) => setRows((r) => r.map((row, idx) => idx === i ? { ...row, [field]: value } : row)); 883 const handleSubmit = () => { 884 const valid = rows.filter((r) => r.commissionEarned && parseFloat(r.commissionEarned) > 0); 885 if (valid.length === 0) { 886 toast.error("At least one transaction with a commission amount is required"); 887 return; 888 } 889 addTxns.mutate({ statementId, transactions: valid.map((r) => ({ ...r, period })) }); 890 }; 891 return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open, onOpenChange: setOpen, children: [ 892 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", className: "gap-1 border-[#3C3B6E] text-[#3C3B6E]", children: [
893 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-3 h-3" }), 894 " ", 895 triggerLabel ?? "Add Transactions" 896 ] }) }), 897 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-4xl max-h-[80vh] overflow-y-auto", children: [ 898 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-[#3C3B6E]", children: [ 899 "Add Transactions â Statement #", 900 statementId 901 ] }) }), 902 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 pt-2", children: [ 903 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs border-collapse", children: [ 904 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "bg-[#3C3B6E] text-white", children: [ 905 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Account" }),
906 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Policy #" }), 907 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Carrier" }), 908 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "LOB" }), 909 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Type" }), 910 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Commission $" }), 911 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Agent Key" }), 912 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Dup?" }), 913 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Adj?" }) 914 ] }) }), 915 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-gray-100", children: [
916 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { value: row.accountName, onChange: (e) => updateRow(i, "accountName", e.target.value), className: "h-7 text-xs" }) }), 917 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { value: row.policyNumber, onChange: (e) => updateRow(i, "policyNumber", e.target.value), className: "h-7 text-xs" }) }), 918 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: row.carrier, onValueChange: (v) => updateRow(i, "carrier", v), children: [ 919 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Carrier" }) }), 920 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: CARRIERS.map((c) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: c, children: c }, c)) }) 921 ] }) }),
922 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: row.lineOfBusiness, onValueChange: (v) => updateRow(i, "lineOfBusiness", v), children: [ 923 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "LOB" }) }), 924 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: ["P&C", "Business", "Life", "Auto", "Home", "Umbrella", "BOP", "GL", "Cyber", "E&O"].map((l) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: l, children: l }, l)) }) 925 ] }) }), 926 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: row.transactionType, onValueChange: (v) => updateRow(i, "transactionType", v), children: [ 927 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }),
928 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: ["New Business", "Renewal", "Endorsement", "Cancellation", "Reinstatement"].map((t) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: t, children: t }, t)) }) 929 ] }) }), 930 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", step: "0.01", value: row.commissionEarned, onChange: (e) => updateRow(i, "commissionEarned", e.target.value), className: "h-7 text-xs w-24", placeholder: "0.00" }) }), 931 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: row.assignedAgentKey, onValueChange: (v) => updateRow(i, "assignedAgentKey", v), children: [ 932 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Agent" }) }), 933 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 934 SUB_AGENTS.map((a) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: a.key, children: a.key }, a.key)),
935 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "Agency", children: "Agency" }) 936 ] }) 937 ] }) }), 938 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("input", { type: "checkbox", checked: row.isDuplicate, onChange: (e) => updateRow(i, "isDuplicate", e.target.checked) }) }), 939 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-1 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("input", { type: "checkbox", checked: row.isAdjustment, onChange: (e) => updateRow(i, "isAdjustment", e.target.checked) }) }) 940 ] }, i)) }) 941 ] }) }), 942 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 943 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", onClick: addRow, className: "gap-1", children: [ 944 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-3 h-3" }), 945 " Add Row" 946 ] }),
947 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: handleSubmit, disabled: addTxns.isPending, className: "bg-[#3C3B6E] hover:bg-[#3C3B6E] text-white", children: addTxns.isPending ? "Saving..." : `Save ${rows.length} Transaction${rows.length !== 1 ? "s" : ""}` }) 948 ] }) 949 ] }) 950 ] }) 951 ] }); 952} 953function CalculateSplitsModal({ statementId, onSuccess }) { 954 const [open, setOpen] = reactExports.useState(false); 955 const [overrides, setOverrides] = reactExports.useState( 956 AGENT_SPLIT_RULES.map((a) => ({ agentId: a.id, profitSharing: 0, balanceAdjustment: 0 })) 957 ); 958 const calcSplits = trpc.commissions.calculateSplits.useMutation({ 959 onSuccess: (d) => { 960 toast.success(`Splits calculated for ${d.splits.length} agents`); 961 setOpen(false); 962 onSuccess(); 963 }, 964 onError: (e) => toast.error(e.message) 965 }); 966 const updateOverride = (idx, field, value) => setOverrides((s) => s.map((o, i) => i === idx ? { ...o, [field]: value } : o)); 967 const handleCalculate = () => { 968 calcSplits.mutate({ 969 statementId, 970 agentOverrides: overrides 971 }); 972 }; 973 return /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open, onOpenChange: setOpen, children: [ 974 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", className: "gap-1 bg-[#B22234] hover:bg-[#b8973e] text-white", children: [
975 /* @__PURE__ */ jsxRuntimeExports.jsx(Calculator, { className: "w-3 h-3" }), 976 " Calculate Splits" 977 ] }) }), 978 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-3xl", children: [ 979 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-[#3C3B6E]", children: [ 980 "Calculate Commission Splits â Statement #", 981 statementId 982 ] }) }), 983 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 pt-2", children: [ 984 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded p-3 text-xs text-blue-800", children: [ 985 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Automatic Split Rules:" }), 986 " Percentages are applied per transaction based on carrier. Progressive, ASI, Celina & Hanover use higher rates. Josh Hinkle also receives 10% of Zach Hinkle's commissions." 987 ] }), 988 /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-sm border-collapse", children: [
989 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "bg-[#3C3B6E] text-white text-xs", children: [ 990 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Agent" }), 991 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "SIAA Rate" }), 992 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Non-SIAA Rate" }), 993 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Profit Sharing" }), 994 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Balance Adjustment" }), 995 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Notes" }) 996 ] }) }), 997 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: AGENT_SPLIT_RULES.map((agent, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-gray-100", children: [
998 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 font-medium text-[#3C3B6E]", children: agent.name }), 999 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-block bg-[#3C3B6E]/10 text-[#3C3B6E] font-semibold rounded px-2 py-0.5 text-xs", children: [ 1000 Math.round(agent.standard * 100), 1001 "%" 1002 ] }) }), 1003 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-block bg-[#B22234]/20 text-[#8a6d1a] font-semibold rounded px-2 py-0.5 text-xs", children: [ 1004 Math.round(agent.master * 100), 1005 "%" 1006 ] }) }), 1007 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 justify-center", children: [ 1008 /* @__P
1008URE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "$" }), 1009 /* @__PURE__ */ jsxRuntimeExports.jsx( 1010 Input, 1011 { 1012 type: "number", 1013 min: "0", 1014 step: "0.01", 1015 value: overrides[i].profitSharing, 1016 onChange: (e) => updateOverride(i, "profitSharing", parseFloat(e.target.value) || 0), 1017 className: "h-7 w-24 text-xs", 1018 placeholder: "0.00" 1019 } 1020 ) 1021 ] }) }), 1022 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 justify-center", children: [ 1023 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "$" }), 1024 /* @__PURE__ */ jsxRuntimeExports.jsx( 1025 Input, 1026 { 1027 type: "number", 1028 step: "0.01", 1029 value: overrides[i].balanceAdjustment, 1030 onChange: (e) => updateOverride(i, "balanceAdjustment", parseFloat(e.target.value) || 0), 1031 className: "h-7 w-24 text-xs", 1032 placeholder: "0.00" 1033 } 1034 ) 1035 ] }) }),
1036 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-xs text-gray-500 italic", children: agent.note }) 1037 ] }, agent.id)) }) 1038 ] }), 1039 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: handleCalculate, disabled: calcSplits.isPending, className: "w-full bg-[#3C3B6E] hover:bg-[#3C3B6E] text-white", children: calcSplits.isPending ? "Calculating..." : "Calculate & Save Splits" }) 1040 ] }) 1041 ] }) 1042 ] }); 1043} 1044function StatementDetail({ statementId, period, isAdmin, onBack, agentId }) { 1045 const { data: txnData, refetch: refetchTxns } = trpc.commissions.listTransactions.useQuery({ statementId, limit: 2e3 }, { retry: false }); 1046 const { data: splits, refetch: refetchSplits } = trpc.commissions.getSplits.useQuery({ statementId }, { retry: false }); 1047 const { data: adjustments, refetch: refetchAdj } = trpc.commissions.listAdjustments.useQuery( 1048 { statementId }, 1049 { enabled: isAdmin || Boolean(agentId), retry: false, refetchOnWindowFocus: true } 1050 ); 1051 const { data: stmtFiles, refetch: refetchFiles } = trpc.commissions.listStatementFiles.useQuery( 1052 { statementId }, 1053 { enabled: isAdmin, retry: false } 1054 ); 1055 const removeFile = trpc.commissions.removeStatementFile.useMutation({ 1056 onSuccess: async () => { 1057 await Promise.all([refetchFiles(), refetchTxns(), refetchSplits(), refetchAdj()]); 1058 toast.success("Source file removed. Unified totals were recalculated and eligible producers were notified."); 1059 }, 1060 onError: (e) => toast.error(e.message) 1061 }); 1062 const [adjAgentId, setAdjAgentId] = reactExports.useState(""); 1063 const [adjMessage, setAdjMessage] = reactExports.useState(""); 1064 const [aiSuggestions, setAiSuggestions] = reactExports.useState([]); 1065 const [manualType, setManualType] = reactExports.useState("add"); 1066 const [manualAmount, setManualAmount] = reactExports.useState(""); 1067 const [manualDesc, setManualDesc] = reactExports.useState(""); 1068 const [manualPolicy, setManualPolicy] = reactExports.useState(""); 1069 const [manualCarrier, setManualCarrier] = reactExports.useState(""); 1070 const [adjConfirm, setAdjConfirm] = reactExports.useState(null); 1071 const [notificationPreview, setNotificationPreview] = reactExports.useState(null); 1072 const aiSuggest = trpc.commissions.aiSuggestAdjustments.useMutation({ 1073 onSuccess: (data) => { 1074 setAiSuggestions(data.suggestions); 1075 if (data.suggestions.length === 0) toast.info("AI found no adjustments needed based on your description."); 1076 else toast.success(`AI suggested ${data.suggestions.length} adjustment${data.suggestions.length > 1 ? "s" : ""}.`); 1077 }, 1078 onError: (e) => toast.error(e.message) 1079 }); 1080 const previewNotification = trpc.commissions.previewNotification.useMutation({ 1081 onSuccess: (data) => setNotificationPreview(data), 1082 onError: (e) => toast.error(`Adjustment saved, but notification preview failed: ${e.message}`) 1083 }); 1084 const sendPreviewedNotification = trpc.commissions.sendPreviewedNotification.useMutation({ 1085 onSuccess: (data) => { 1086 const sentCount = data.results.filter((result) => result.sent).length; 1087 const skippedCount = data.results.filter((result) => result.skipped).length; 1088 setNotificationPreview(null); 1089 toast.success(`${sentCount} notification group${sentCount === 1 ? "" : "s"} sent${skippedCount ? `; ${skippedCount} already sent` : ""}.`); 1090 }, 1091 onError: (e) => toast.error(e.message) 1092 }); 1093 const addAdj = trpc.commissions.addAdjustment.useMutation({ 1094 onSuccess: async (data) => { 1095 await Promise.all([refetchAdj(), refetchSplits()]); 1096 setAdjConfirm(null); 1097 setManualAmount(""); 1098 setManualDesc(""); 1099 setManualPolicy(""); 1100 setManualCarrier(""); 1101 toast.success("Adjustment saved. No email has been sentâreview recipients and confirm delivery."); 1102 previewNotification.mutate(data.notification); 1103 }, 1104 onError: (e) => toast.error(e.message) 1105 }); 1106 const removeAdj = trpc.commissions.removeAdjustment.useMutation({ 1107 onSuccess: async (data) => { 1108 await Promise.all([refetchAdj(), refetchSplits()]); 1109 if (data.notification) { 1110 toast.success("Adjustment removed. No email has been sentâreview recipients and confirm delivery."); 1111 previewNotification.mutate(data.notification); 1112 } else { 1113 toast.info("Adjustment was already absent; no notification is required."); 1114 } 1115 }, 1116 onError: (e) => toast.error(e.message) 1117 }); 1118 const selectedAgentName = AGENT_SPLIT_RULES.find((a) => a.id === adjAgentId)?.name ?? adjAgentId; 1119 const exportAgentStatement = trpc.commissions.exportAgentStatement.useMutation({ 1120 onSuccess: (data) => { 1121 const bytes = Uint8Array.from(atob(data.base64), (c) =>
1121 c.charCodeAt(0)); 1122 const blob = new Blob([bytes], { type: data.mimeType }); 1123 const url = URL.createObjectURL(blob); 1124 const a = document.createElement("a"); 1125 a.href = url; 1126 a.download = data.filename; 1127 a.click(); 1128 URL.revokeObjectURL(url); 1129 toast.success(`${data.filename} downloaded`); 1130 }, 1131 onError: (e) => toast.error(e.message) 1132 }); 1133 trpc.commissions.exportStatement.useMutation({ 1134 onSuccess: (data) => { 1135 const bytes = Uint8Array.from(atob(data.base64), (c) => c.charCodeAt(0)); 1136 const blob = new Blob([bytes], { type: data.mimeType }); 1137 const url = URL.createObjectURL(blob); 1138 const a = document.createElement("a"); 1139 a.href = url; 1140 a.download = data.filename; 1141 a.click(); 1142 URL.revokeObjectURL(url); 1143 toast.success(`${data.filename} downloaded`); 1144 }, 1145 onError: (e) => toast.error(e.message) 1146 }); 1147 const exportAgencyRollup = trpc.commissions.exportAgencyRollup.useMutation({ 1148 onSuccess: (data) => { 1149 const bytes = Uint8Array.from(atob(data.base64), (c) => c.charCodeAt(0)); 1150 const blob = new Blob([bytes], { type: data.mimeType }); 1151 const url = URL.createObjectURL(blob); 1152 const a = document.createElement("a"); 1153 a.href = url; 1154 a.download = data.filename; 1155 a.click(); 1156 URL.revokeObjectURL(url); 1157 toast.success(`${data.filename} downloaded`); 1158 }, 1159 onError: (e) => toast.error(e.message) 1160 }); 1161 trpc.commissions.markReported.useMutation({ 1162 onSuccess: () => { 1163 toast.success("Statement marked as reported"); 1164 onBack(); 1165 }, 1166 onError: (e) => toast.error(e.message) 1167 }); 1168 const recalculate = trpc.commissions.calculateSplits.useMutation({ 1169 onSuccess: () => { 1170 toast.success("Splits recalculated."); 1171 refetchSplits(); 1172 }, 1173 onError: (e) => toast.error(e.message) 1174 }); 1175 const [isPdfGenerating, setIsPdfGenerating] = reactExports.useState(false); 1176 const downloadAgentPDF = reactExports.useCallback(async (targetAgentId) => { 1177 const targetSplit = (splits ?? []).find((s) => s.agentId === targetAgentId); 1178 if (!targetSplit) { 1179 toast.error("No split data found â please calculate splits first"); 1180 return; 1181 } 1182 setIsPdfGenerating(true); 1183 try { 1184 const { jsPDF } = await __vitePreload(async () => { const { jsPDF } = await import('./jspdf.es.min-CWHF2JOV.js').then(n => n.j);return { jsPDF }},true ?__vite__mapDeps([0,1,2]):void 0); 1185 const doc = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4" }); 1186 const pageW = doc.internal.pageSize.getWidth(); 1187 const pageH = doc.internal.pageSize.getHeight(); 1188 const mg = 15; 1189 const cW = pageW - mg * 2; 1190 const FOOTER_H = 14; 1191 const SAFE_BOT = pageH - FOOTER_H - 4; 1192 const NAVY = [10, 35, 66]; 1193 const GOLD = [201, 168, 76]; 1194 const GREEN = [22, 163, 74]; 1195 const GRAY = [107, 114, 128]; 1196 const LGRAY = [229, 231, 235]; 1197 const WHITE = [255, 255, 255]; 1198 const FAINT = [248, 249, 250]; 1199 const DARK = [30, 30, 30]; 1200 const PURPLE = [109, 40, 217]; 1201 const AMBER = [180, 83, 9]; 1202 const cws = [cW * 0.32, cW * 0.14, cW * 0.16, cW * 0.12, cW * 0.14, cW * 0.12]; 1203 const cxs = [mg, mg + cws[0], mg + cws[0] + cws[1], mg + cws[0] + cws[1] + cws[2], mg + cws[0] + cws[1] + cws[2] + cws[3], mg + cws[0] + cws[1] + cws[2] + cws[3] + cws[4]]; 1204 const pdfFmt = (v) => { 1205 const n = parseFloat(String(v ?? 0)); 1206 return isNaN(n) ? "$0.00" : n.toLocaleString("en-US", { style: "currency", currency: "USD" }); 1207 }; 1208 const drawHdr = () => { 1209 doc.setFillColor(...NAVY); 1210 doc.rect(0, 0, pageW, 26, "F"); 1211 doc.setTextColor(...WHITE); 1212 doc.setFontSize(15); 1213 doc.setFont("helvetica", "bold"); 1214 doc.text("Expert Protection Services", mg, 11); 1215 doc.setFontSize(8); 1216 doc.setFont("helvetica", "normal"); 1217 doc.setTextColor(...GOLD); 1218 doc.text("COMMISSION STATEMENT â CONFIDENTIAL", mg, 19); 1219 doc.setTextColor(200, 200, 200); 1220 doc.text((/* @__PURE__ */ new Date()).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "
1220numeric" }), pageW - mg, 19, { align: "right" }); 1221 }; 1222 const drawFtr = (pg, tot) => { 1223 doc.setFillColor(...NAVY); 1224 doc.rect(0, pageH - FOOTER_H, pageW, FOOTER_H, "F"); 1225 doc.setFontSize(7); 1226 doc.setFont("helvetica", "normal"); 1227 doc.setTextColor(200, 200, 200); 1228 doc.text(`${targetSplit.agentName} · Expert Protection Services · Confidential`, mg, pageH - 4); 1229 doc.text(`Page ${pg} of ${tot}`, pageW - mg, pageH - 4, { align: "right" }); 1230 }; 1231 const drawTxHdr = (yp) => { 1232 doc.setFillColor(...NAVY); 1233 doc.rect(mg, yp, cW, 9, "F"); 1234 doc.setTextColor(...WHITE); 1235 doc.setFontSize(7); 1236 doc.setFont("helvetica", "bold"); 1237 ["Account Name", "Policy #", "Carrier", "Type", "Commission", "Agent Due"].forEach((h, i) => doc.text(h, cxs[i] + 2, yp + 6)); 1238 return yp + 9; 1239 }; 1240 const drawTxRow = (t, idx, yp, sp) => { 1241 doc.setFontSize(7); 1242 doc.setFont("helvetica", "normal"); 1243 const nl = doc.splitTextToSize(t.accountName ?? "", cws[0] - 4); 1244 const rH = Math.max(nl.length * 4.2 + 3, 8); 1245 if (yp + rH > SAFE_BOT) { 1246 doc.addPage(); 1247 drawHdr(); 1248 yp = drawTxHdr(30); 1249 } 1250 doc.setFillColor(...idx % 2 === 0 ? WHITE : FAINT); 1251 doc.rect(mg, yp, cW, rH, "F"); 1252 doc.setDrawColor(...LGRAY); 1253 doc.setLineWidth(0.2); 1254 doc.line(mg, yp + rH, mg + cW, yp + rH); 1255 [1, 2, 3, 4, 5].forEach((ci) => doc.line(cxs[ci], yp, cxs[ci], yp + rH)); 1256 const ty = yp + 3.5; 1257 doc.setTextColor(...DARK); 1258 doc.text(nl, cxs[0] + 2, ty, { lineHeightFactor: 1.4 }); 1259 doc.setTextColor(...GRAY); 1260 doc.text(t.policyNumber ?? "", cxs[1] + 2, ty); 1261 doc.text(t.carrier ?? "", cxs[2] + 2, ty); 1262 doc.text(t.transactionType ?? "", cxs[3] + 2, ty); 1263 const earned = parseFloat(String(t.commissionEarned ?? 0)); 1264 const due = Math.round(earned * sp * 100) / 100; 1265 doc.setTextColor(...DARK); 1266 doc.text(pdfFmt(earned), cxs[4] + cws[4] - 2, ty, { align: "right" }); 1267 doc.setTextColor(...GREEN); 1268 doc.setFont("helvetica", "bold"); 1269 doc.text(pdfFmt(due), cxs[5] + cws[5] - 2, ty, { align: "right" }); 1270 doc.setFont("helvetica", "normal"); 1271 doc.setTextColor(...DARK); 1272 return yp + rH; 1273 }; 1274 const agentKey = AGENT_SPLIT_RULES.find((r) => r.id === targetAgentId)?.key ?? ""; 1275 const agentTxns = (txnData?.items ?? []).filter((t) => !t.isDuplicate && t.assignedAgentKey === agentKey); 1276 const MASTER_C = ["celina", "progressive", "prg"]; 1277 const isMC = (c) => MASTER_C.includes((c ?? "").trim().toLowerCase()); 1278 const rule = AGENT_SPLIT_RULES.find((r) => r.id === targetAgentId); 1279 const siaaTxns = agentTxns.filter((t) => !isMC(t.carrier)); 1280 const nonSiaaTxns = agentTxns.filter((t) => isMC(t.carrier)); 1281 const stdPct = rule?.standard ?? 0.7; 1282 const mstPct = rule?.master ?? 0.8; 1283 drawHdr(); 1284 let y = 32; 1285 doc.setFillColor(...FAINT); 1286 doc.rect(mg, y, cW, 28, "F"); 1287 doc.setDrawColor(...LGRAY); 1288 doc.setLineWidth(0.3); 1289 doc.rect(mg, y, cW, 28); 1290 doc.setFillColor(...GOLD); 1291 doc.rect(mg, y, 3, 28, "F"); 1292 doc.setFontSize(13); 1293 doc.setFont("helvetica", "bold"); 1294 doc.setTextColor(...NAVY); 1295 doc.text(targetSplit.agentName, mg + 7, y + 9); 1296 doc.setFontSize(8); 1297 doc.setFont("helvetica", "normal"); 1298 doc.setTextColor(...GRAY); 1299 doc.text(`Statement Period: ${period}`, mg + 7, y + 17); 1300 doc.text(`${agentTxns.length} transactions · Effective rate: ${Math.round(parseFloat(String(targetSplit.splitPct ?? 0)) * 100)}%`, mg + 7, y + 23); 1301 doc.setFontSize(11); 1302 doc.setFont("helvetica", "bold"); 1303 doc.setTextColor(...GOLD); 1304 doc.text(pdfFmt(targetSplit.grandTotal), pageW - mg - 4, y + 9, { align: "right" }); 1305 doc.setFontSize(7); 1306 doc.setFont("helvetica", "normal"); 1307 doc.setTextColor(...GRAY); 1308 doc.text("GRAND TOTAL DUE", pageW - mg - 4, y + 16, { align: "right" }); 1309 y += 34; 1310 if (siaaTxns.length > 0) { 1311 doc.setFillColor(...NAVY); 1312 doc.rect(mg, y, cW, 8, "F"); 1313 doc.setTextColor(...WHITE); 1314 doc.setFontSize(8); 1315 doc.setFont("helvetica", "bold"); 1316 doc.text(`SIAA Commissions â ${Math.round(stdPct * 100)}% Split (${siaaTxns.length} transactions)`, mg + 4, y + 5.5); 1317 y += 8; 1318 y = drawTxHdr(y); 1319 siaaTxns.forEach((t, i) => { 1320 y = drawTxRow(t, i, y, stdPct); 1321 }); 1322 const siaaE = siaaTxns.reduce((s, t) => s + parseFloat(String(t.commissionEarned ?? 0)), 0); 1323 const siaaD = Math.round(siaaE * stdPct * 100) / 100; 1324 if (y + 9 > SAFE_BOT) { 1325 doc.addPage(); 1326 drawHdr(); 1327 y = 30; 1328 } 1329 doc.setFillColor(220, 240, 220); 1330 doc.rect(mg, y, cW, 9, "F"); 1331 doc.setDrawColor(...GREEN); 1332 doc.setLineWidth(0.3); 1333 doc.rect(mg, y, cW, 9); 1334 doc.setFontSize(8); 1335 doc.setFont("helvetica", "bold"); 1336 doc.setTextColor(...GREEN); 1337 doc.text("SIAA Subtotal", mg + 4, y + 6); 1338 doc.text(pdfFmt(siaaE), cxs[4] + cws[4] - 2, y + 6, { align: "right" }); 1339 doc.text(pdfFmt(siaaD), cxs[5] + cws[5] - 2, y + 6, { align: "right" }); 1340 y += 13; 1341 } 1342 if (nonSiaaTxns.length > 0) { 1343 if (y + 20 > SAFE_BOT) { 1344 doc.addPage(); 1345 drawHdr(); 1346 y = 30; 1347 } 1348 doc.setFillColor(...NAVY); 1349 doc.rect(mg, y, cW, 8, "F"); 1350 doc.setTextColor(...WHITE); 1351 doc.setFontSize(8); 1352 doc.setFont("helvetica", "bold"); 1353 doc.text(`Non-SIAA / Manual Commissions â ${Math.round(mstPct * 100)}% Split (${nonSiaaTxns.length} transactions)`, mg + 4, y + 5.5); 1354 y += 8; 1355 y = drawTxHdr(y); 1356 nonSiaaTxns.forEach((t, i) => { 1357 y = drawTxRow(t, i, y, mstPct); 1358 }); 1359 const nonE = nonSiaaTxns.reduce((s, t) => s + parseFloat(String(t.commissionEarned ?? 0)), 0); 1360 const nonD = Math.round(nonE * mstPct * 100) / 100; 1361 if (y + 9 > SAFE_BOT) { 1362 doc.addPage(); 1363 drawHdr(); 1364 y = 30; 1365 } 1366 doc.setFillColor(220, 240, 220); 1367 doc.rect(mg, y, cW, 9, "F"); 1368 doc.setDrawColor(...GREEN); 1369 doc.setLineWidth(0.3); 1370 doc.rect(mg, y, cW, 9); 1371 doc.setFontSize(8); 1372 doc.setFont("helvetica", "bold"); 1373 doc.setTextColor(...GREEN); 1374 doc.text("Non-SIAA Subtotal", mg + 4, y + 6); 1375 doc.text(pdfFmt(nonE), cxs[4] + cws[4] - 2, y + 6, { align: "right" }); 1376 doc.text(pdfFmt(nonD), cxs[5] + cws[5] - 2, y + 6, { align: "right" }); 1377 y += 13; 1378 }
1379 const ps = parseFloat(String(targetSplit.profitSharing ?? 0)); 1380 const ba = parseFloat(String(targetSplit.balanceAdjustment ?? 0)); 1381 const targetAdjustments = (adjustments ?? []).filter((a) => a.agentId === targetSplit.agentId); 1382 const targetAdjustmentTotal = targetAdjustments.reduce((sum, a) => { 1383 const amount = parseFloat(String(a.amount ?? 0)); 1384 return sum + (a.type === "deduct" ? -amount : amount); 1385 }, 0); 1386 if (ps !== 0 || ba !== 0 || targetAdjustments.length > 0) { 1387 if (y + 20 > SAFE_BOT) { 1388 doc.addPage(); 1389 drawHdr(); 1390 y = 30; 1391 } 1392 doc.setFontSize(9); 1393 doc.setFont("helvetica", "bold"); 1394 doc.setTextColor(...NAVY); 1395 doc.text(`${period} COMMISSION ADJUSTMENTS`, mg, y); 1396 y += 5; 1397 doc.setDrawColor(...GOLD); 1398 doc.setLineWidth(0.4); 1399 doc.line(mg, y, mg + 36, y); 1400 doc.setLineWidth(0.2); 1401 y += 4; 1402 if (ps !== 0) { 1403 doc.setFontSize(8); 1404 doc.setFont("helvetica", "normal"); 1405 doc.setTextColor(...AMBER); 1406 doc.text("Hanover Profit Sharing Bonus", mg + 4, y + 5); 1407 doc.setFont("helvetica", "bold"); 1408 doc.text(pdfFmt(ps), pageW - mg - 4, y + 5, { align: "right" }); 1409 y += 10; 1410 } 1411 if (ba !== 0) { 1412 const ac = ba < 0 ? [220, 38, 38] : [59, 130, 246]; 1413 doc.setFontSize(8); 1414 doc.setFont("helvetica", "normal"); 1415 doc.setTextColor(...ac); 1416 doc.text("Balance Adjustment", mg + 4, y + 5); 1417 doc.setFont("helvetica", "bold"); 1418 doc.text(pdfFmt(ba), pageW - mg - 4, y + 5, { align: "right" }); 1419 y += 10; 1420 } 1421 targetAdjustments.forEach((adjustment) => { 1422 const amount = parseFloat(String(adjustment.amount ?? 0)); 1423 const signedAmount = adjustment.type === "deduct" ? -amount : amount; 1424 const typeLabel = adjustment.type === "bonus" ? "Bonus" : adjustment.type === "deduct" ? "Deduction" : "Addition"; 1425 const description = `${typeLabel}: ${adjustment.description}${adjustment.policyNumber ? ` · Policy ${adjustment.policyNumber}` : ""}`; 1426 const descriptionLines = doc.splitTextToSize(description, cW - 48); 1427 const rowHeight = Math.max(9, descriptionLines.length * 4 + 3); 1428 if (y + rowHeight > SAFE_BOT) { 1429 doc.addPage(); 1430 drawHdr(); 1431 y = 30; 1432 } 1433 doc.setFillColor(245, 235, 255); 1434 doc.rect(mg, y, cW, rowHeight, "F"); 1435 doc.setFontSize(7); 1436 doc.setFont("helvetica", "normal"); 1437 doc.setTextColor(...PURPLE); 1438 doc.text(descriptionLines, mg + 4, y + 4, { lineHeightFactor: 1.35 }); 1439 doc.setFontSize(8); 1440 doc.setFont("helvetica", "bold"); 1441 doc.text(pdfFmt(signedAmount), pageW - mg - 4, y + 5, { align: "right" }); 1442 y += rowHeight + 1; 1443 }); 1444 if (targetAdjustments.length > 0) { 1445 if (y + 9 > SAFE_BOT) { 1446 doc.addPage(); 1447 drawHdr(); 1448 y = 30; 1449 } 1450 doc.setDrawColor(...PURPLE); 1451 doc.line(mg, y, mg + cW, y); 1452 y += 2; 1453 doc.setFontSize(8); 1454 doc.setFont("helvetica", "bold"); 1455 doc.setTextColor(...PURPLE); 1456 doc.text("Commission Adjustments Included in Grand Total Due", mg + 4, y + 5); 1457 doc.text(pdfFmt(targetAdjustmentTotal), pageW - mg - 4, y + 5, { align: "right" }); 1458 y += 10; 1459 } 1460 } 1461 const isJosh = targetAgentId === "hinkle-josh"; 1462 const zSplit = isJosh ? (splits ?? []).find((s) => s.agentId === "hinkle-zach") : null; 1463 const zBonus = zSplit ? Math.round(parseFloat(String(zSplit.agentDue ?? 0)) * 0.1 * 100) / 100 : 0; 1464 if (zBonus > 0) { 1465 if (y + 14 > SAFE_BOT) { 1466 doc.addPage(); 1467 drawHdr(); 1468 y = 30; 1469 } 1470 doc.setFillColor(245, 235, 255); 1471 doc.rect(mg, y, cW, 12, "F"); 1472 doc.setDrawColor(...PURPLE); 1473 doc.setLineWidth(0.3); 1474 doc.rect(mg, y, cW, 12); 1475 doc.setFillColor(...PURPLE); 1476 doc.rect(mg, y, 3, 12, "F"); 1477 doc.setFontSize(8); 1478 doc.setFont("helvetica", "bold"); 1479 doc.setTextColor(...PURPLE); 1480 doc.text(`10% of Zach Hinkle's Commissions (Zach total: ${pdfFmt(zSplit?.agentDue)})`, mg + 6, y + 5); 1481 doc.setFontSize(7); 1482 doc.setFont("helvetica", "italic"); 1483 doc.setTextColor(109, 40, 217); 1484 doc.text("Included in Grand Total below", mg + 6, y + 10); 1485 doc.setFontSize(9); 1486 doc.setFont("helvetica", "bold"); 1487 doc.setTextColor(...PURPLE); 1488 doc.text(pdfFmt(zBonus), pageW - mg - 4, y + 7, { align: "right" }); 1489 y += 16; 1490 } 1491 if (y + 18 > SAFE_BOT) { 1492 doc.addPage(); 1493 drawHdr(); 1494 y = 30; 1495 } 1496 doc.setFillColor(...NAVY); 1497 doc.rect(mg, y, cW, 16, "F"); 1498 doc.setDrawColor(...GOLD); 1499 doc.setLineWidth(0.5); 1500 doc.rect(mg, y, cW, 16); 1501 doc.setFontSize(10); 1502 doc.setFont("helvetica", "bold"); 1503 doc.setTextColor(...GOLD); 1504 doc.text(`GRAND TOTAL DUE â ${targetSplit.agentName}`, mg + 6, y + 7); 1505 doc.setFontSize(8); 1506 doc.setFont("helvetica", "normal"); 1507 doc.setTextColor(200, 200, 200); 1508 doc.text(`Agent Due: ${pdfFmt(targetSplit.agentDue)} · Commission Adjustments: ${pdfFmt(targetAdjustmentTotal)}`, mg + 6, y + 13); 1509 doc.setFontSize(13); 1510 doc.setFont("helvetica", "bold"); 1511 doc.setTextColor(...GOLD); 1512 doc.text(pdfFmt(targetSplit.grandTotal), pageW - mg - 4, y + 10, { align: "right" }); 1513 const totPgs = doc.internal.getNumberOfPages(); 1514 for (let i = 1; i <= totPgs; i++) { 1515 doc.setPage(i); 1516 drawFtr(i, totPgs); 1517 } 1518 const slug = (targetSplit.agentName ?? "agent").toLowerCase().replace(/\s+/g, "-"); 1519 doc.save(`commission-statement-${period.replace(/\s+/g, "-")}-${slug}.pdf`); 1520 toast.success(`PDF downloaded for ${targetSplit.agentName}`); 1521 } catch (err) { 1522 console.error(err); 1523 toast.error("Failed to generate PDF"); 1524 } finally { 1525 setIsPdfGenerating(false); 1526 } 1527 }, [splits, txnData, adjustments, period]); 1528 const txns = txnData?.items ?? []; 1529 const { activeTxns, totalActive, duplicateCount } = reactExports.useMemo(() => { 1530 const active = txns.filter((t) => !t.isDuplicate); 1531 return { 1532 activeTxns: active, 1533 totalActive: active.reduce((s, t) => s + parseFloat(t.commissionEarned || "0"), 0), 1534 duplicateCount: txns.filter((t) =>
1534 t.isDuplicate).length 1535 }; 1536 }, [txns]); 1537 const { mySplit, zachSplit, zachBonus, directCommissions } = reactExports.useMemo(() => { 1538 const my = !isAdmin && agentId ? (splits ?? []).find((s) => s.agentId === agentId && s.lineType !== "zach_override") ?? null : null; 1539 const zachOverrideRow = (splits ?? []).find((s) => s.lineType === "zach_override"); 1540 const zach = (splits ?? []).find( 1541 (s) => s.agentId === "hinkle-zach" || s.agentId === "zach-hinkle" 1542 ); 1543 const isJosh = agentId === "josh-hinkle" || agentId === "hinkle-josh"; 1544 const bonus = isJosh && zachOverrideRow ? Math.round(parseFloat(String(zachOverrideRow.agentDue ?? "0")) * 100) / 100 : isJosh && zach ? Math.round(parseFloat(String(zach.agentDue ?? "0")) * 0.1 * 100) / 100 : 0; 1545 const direct = my ? parseFloat(String(my.agentDue ?? "0")) + parseFloat(String(my.profitSharing ?? "0")) + parseFloat(String(my.balanceAdjustment ?? "0")) : 0; 1546 return { mySplit: my, zachSplit: zach ?? null, zachBonus: bonus, directCommissions: direct }; 1547 }, [splits, isAdmin, agentId]); 1548 const adjustmentTotalsByAgent = reactExports.useMemo(() => { 1549 const totals = /* @__PURE__ */ new Map(); 1550 for (const adjustment of adjustments ?? []) { 1551 const signedAmount = adjustment.type === "deduct" ? -parseFloat(String(adjustment.amount ?? "0")) : parseFloat(String(adjustment.amount ?? "0")); 1552 totals.set(adjustment.agentId, (totals.get(adjustment.agentId) ?? 0) + signedAmount); 1553 } 1554 return totals; 1555 }, [adjustments]); 1556 const myAdjustments = reactExports.useMemo( 1557 () => mySplit ? (adjustments ?? []).filter((adjustment) => adjustment.agentId === mySplit.agentId) : [], 1558 [adjustments, mySplit] 1559 ); 1560 const myAdjustmentTotal = mySplit ? adjustmentTotalsByAgent.get(mySplit.agentId) ?? 0 : 0; 1561 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ 1562 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
1563 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: onBack, className: "text-[#3C3B6E]", children: "â Back to Statements" }), 1564 /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-[#3C3B6E]", children: [ 1565 "Statement #", 1566 statementId, 1567 " â ", 1568 period 1569 ] }) 1570 ] }), 1571 isAdmin && stmtFiles && stmtFiles.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: [ 1572 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [ 1573 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-[#3C3B6E] flex items-center gap-2", children: [ 1574 /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-4 h-4" }), 1575 "Uploaded Files for ", 1576 period, 1577 " (", 1578 stmtFiles.length, 1579 " file", 1580 stmtFiles.length !== 1 ? "s" : "", 1581 ")" 1582 ] }),
1583 /* @__PURE__ */ jsxRuntimeExports.jsx( 1584 AddTransactionsModal, 1585 { 1586 statementId, 1587 period, 1588 onSuccess: () => { 1589 refetchTxns(); 1590 refetchSplits(); 1591 refetchFiles(); 1592 }, 1593 triggerLabel: "+ Add More Files" 1594 } 1595 ) 1596 ] }), 1597 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: stmtFiles.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between bg-white border border-blue-100 rounded px-3 py-2", children: [ 1598 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [ 1599 /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-4 h-4 text-green-600 shrink-0" }), 1600 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-800 truncate", children: f.fileName }), 1601 f.carrier && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded", children: f.carrier }),
1602 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `text-xs font-semibold px-2 py-0.5 rounded ${f.sourceCategory === "manual" ? "bg-amber-100 text-amber-800" : "bg-blue-100 text-blue-800"}`, children: f.sourceCategory === "manual" ? "Manual" : "Downloaded" }), 1603 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-400", children: [ 1604 f.transactionCount, 1605 " rows" 1606 ] }), 1607 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-[#3C3B6E]", children: fmtCurrency(f.sourceSubtotal) }) 1608 ] }), 1609 /* @__PURE__ */ jsxRuntimeExports.jsx( 1610 Button, 1611 { 1612 variant: "ghost", 1613 size: "sm", 1614 onClick: () => removeFile.mutate({ fileId: f.id }), 1615 disabled: removeFile.isPending, 1616 className: "text-red-500 hover:text-red-700 hover:bg-red-50 shrink-0 h-7 px-2", 1617 title: "Remove this source file and automatically recalculate the unified statement", 1618 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-3 h-3" }) 1619 } 1620 ) 1621 ] }, f.id)) }) 1622 ] }), 1623 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 flex-wrap", children: [
1624 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(CalculateSplitsModal, { statementId, onSuccess: () => refetchSplits() }), 1625 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs( 1626 Button, 1627 { 1628 variant: "outline", 1629 size: "sm", 1630 onClick: () => recalculate.mutate({ statementId }), 1631 disabled: recalculate.isPending, 1632 className: "gap-1 border-[#3C3B6E] text-[#3C3B6E] hover:bg-[#3C3B6E] hover:text-white", 1633 title: "Recalculate splits using current transactions and saved overrides", 1634 children: [ 1635 recalculate.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "w-3 h-3" }), 1636 "Recalculate" 1637 ] 1638 } 1639 ), 1640 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs( 1641 Button, 1642 { 1643 variant: "outline", 1644 size: "sm", 1645 onClick: () => exportAgencyRollup.mutate({ statementId }), 1646 disabled: exportAgencyRollup.isPending, 1647 className: "gap-1 border-purple-600 text-purple-700 hover:bg-purple-600 hover:text-white", 1648 title: "Download full-agency rollup report with all agents in one Excel file", 1649 children: [
1650 exportAgencyRollup.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-3 h-3" }), 1651 "Download Agency Report" 1652 ] 1653 } 1654 ), 1655 !isAdmin && agentId && /* @__PURE__ */ jsxRuntimeExports.jsxs( 1656 Button, 1657 { 1658 variant: "outline", 1659 size: "sm", 1660 onClick: () => exportAgentStatement.mutate({ statementId, agentId }), 1661 disabled: exportAgentStatement.isPending, 1662 className: "gap-1 border-green-600 text-green-700 hover:bg-green-600 hover:text-white", 1663 children: [ 1664 exportAgentStatement.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-3 h-3" }), 1665 "Download My Statement" 1666 ] 1667 } 1668 ) 1669 ] }), 1670 /* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { defaultValue: isAdmin ? "transactions" : "my-summary", children: [
1671 /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { className: "bg-[#3C3B6E]/10", children: [ 1672 !isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "my-summary", children: "My Commission Summary" }), 1673 /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "transactions", children: [ 1674 "Transactions (", 1675 txns.length, 1676 ")" 1677 ] }), 1678 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "splits", children: [ 1679 "Agent Splits (", 1680 splits?.length ?? 0, 1681 ")" 1682 ] }), 1683 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "adjustments", className: "gap-1", children: [ 1684 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-3 h-3" }), 1685 "AI Adjustments ", 1686 adjustments && adjustments.length > 0 ? `(${adjustments.length})` : "" 1687 ] }) 1688 ] }), 1689 !isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "my-summary", className: "mt-4", children: !mySplit ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12 text-gray-400", children: [
1690 /* @__PURE__ */ jsxRuntimeExports.jsx(Calculator, { className: "w-12 h-12 mx-auto mb-3 opacity-30" }), 1691 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium", children: "No commission data yet for this statement." }), 1692 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "Splits have not been calculated yet. Please check back after the statement is processed." }) 1693 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 1694 /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border border-[#3C3B6E]/20", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-5", children: [ 1695 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4", children: [ 1696 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-base font-bold text-[#3C3B6E]", children: mySplit?.agentName }), 1697 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-right", children: [
1698 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-[#B22234]", children: fmtCurrency(mySplit?.grandTotal) }), 1699 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Total Due This Period" }) 1700 ] }) 1701 ] }), 1702 mySplit && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3", children: [ 1703 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-[#3C3B6E]/60 uppercase tracking-wide mb-2", children: "Direct Commissions" }), 1704 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 mb-2", children: [ 1705 mySplit.transactionCount, 1706 " transactions · ", 1707 fmtPct(mySplit.splitPct), 1708 " effective rate" 1709 ] }), 1710 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2 sm:grid-cols-5", children: [ 1711 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 rounded p-2.5", children: [
1712 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Agency Earned" }), 1713 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-[#3C3B6E]", children: fmtCurrency(mySplit.totalEarned) }) 1714 ] }), 1715 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-green-50 rounded p-2.5", children: [ 1716 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Your Split" }), 1717 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-green-700", children: fmtCurrency(mySplit.agentDue) }) 1718 ] }), 1719 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 rounded p-2.5", children: [ 1720 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-600", children: "Profit Sharing" }), 1721 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-amber-700", children: fmtCurrency(mySplit.profitSharing) }) 1722 ] }),
1723 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 rounded p-2.5", children: [ 1724 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-600", children: "Balance Adj." }), 1725 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-sm font-semibold ${parseFloat(mySplit.balanceAdjustment) < 0 ? "text-red-600" : "text-blue-700"}`, children: fmtCurrency(mySplit.balanceAdjustment) }) 1726 ] }), 1727 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-purple-50 rounded p-2.5", children: [ 1728 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-purple-600", children: "Commission Adjustments" }), 1729 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-sm font-semibold ${myAdjustmentTotal < 0 ? "text-red-700" : "text-purple-700"}`, children: fmtCurrency(myAdjustmentTotal) }) 1730 ] }) 1731 ] }), 1732 zachBonus > 0 || myAdjustments.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex justify-between text-xs text-gray-500 px-1", children: [
1733 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Direct Commissions Subtotal" }), 1734 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[#3C3B6E]", children: fmtCurrency(directCommissions) }) 1735 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex justify-between text-xs text-gray-500 px-1", children: [ 1736 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Subtotal" }), 1737 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[#3C3B6E]", children: fmtCurrency(mySplit.grandTotal) }) 1738 ] }) 1739 ] }), 1740 zachBonus > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 rounded border border-purple-200 bg-purple-50 px-3 py-2.5 flex items-center justify-between", children: [ 1741 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1742 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-purple-800", children: "10% of Zach Hinkle's Commissions" }),
1743 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-purple-500 mt-0.5", children: [ 1744 "Zach's total: ", 1745 fmtCurrency(zachSplit?.agentDue), 1746 " Ã 10%" 1747 ] }) 1748 ] }), 1749 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold text-purple-700", children: fmtCurrency(zachBonus) }) 1750 ] }), 1751 myAdjustments.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 rounded border border-purple-200 bg-purple-50 px-3 py-3", children: [ 1752 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2 flex items-center justify-between gap-3", children: [ 1753 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-bold uppercase tracking-wide text-purple-800", children: [ 1754 period, 1755 " Commission Adjustments" 1756 ] }), 1757 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-sm font-bold ${myAdjustmentTotal < 0 ? "text-red-700" : "text-purple-700"}`, children: fmtCurrency(myAdjustmentTotal) }) 1758 ] }),
1759 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1.5", children: myAdjustments.map((adjustment) => { 1760 const signedAmount = adjustment.type === "deduct" ? -parseFloat(String(adjustment.amount ?? "0")) : parseFloat(String(adjustment.amount ?? "0")); 1761 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-4 text-xs text-purple-900", children: [ 1762 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 1763 adjustment.description, 1764 adjustment.policyNumber ? ` · Policy ${adjustment.policyNumber}` : "" 1765 ] }), 1766 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `shrink-0 font-semibold ${signedAmount < 0 ? "text-red-700" : "text-purple-700"}`, children: fmtCurrency(signedAmount) }) 1767 ] }, adjustment.id); 1768 }) }), 1769 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 border-t border-purple-200 pt-2 text-xs font-semibold text-purple-800", children: "Included in Total Due This Period" }) 1770 ] }),
1771 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t-2 border-[#3C3B6E]/20 mt-4 pt-3 flex justify-between", children: [ 1772 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-bold text-[#3C3B6E]", children: "Total Due This Period" }), 1773 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xl font-bold text-[#B22234]", children: fmtCurrency(mySplit?.grandTotal) }) 1774 ] }) 1775 ] }) }), 1776 agentId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-center gap-3 flex-wrap", children: [ 1777 /* @__PURE__ */ jsxRuntimeExports.jsx( 1778 Button, 1779 { 1780 size: "lg", 1781 onClick: () => exportAgentStatement.mutate({ statementId, agentId }), 1782 disabled: exportAgentStatement.isPending || isPdfGenerating, 1783 className: "gap-2 bg-green-700 hover:bg-green-800 text-white px-8", 1784 children: exportAgentStatement.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1785 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }), 1786 " Generating..." 1787 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1788 /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-4 h-4" }), 1789 " Download My Statement (Excel)" 1790 ] }) 1791 } 1792 ), 1793 /* @__PURE__ */ jsxRuntimeExports.jsx( 1794 Button, 1795 { 1796 size: "lg", 1797 variant: "outline", 1798 onClick: () => downloadAgentPDF(agentId), 1799 disabled: exportAgentStatement.isPending || isPdfGenerating, 1800 className: "gap-2 border-red-600 text-red-700 hover:bg-red-600 hover:text-white px-8", 1801 children: isPdfGenerating ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1802 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }), 1803 " Generating PDF..." 1804 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1805 /* @__PURE__ */ jsxRuntimeExports.jsx(FileDown, { className: "w-4 h-4" }), 1806 " Download My Statement (PDF)" 1807 ] }) 1808 } 1809 ) 1810 ] }), 1811 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-[#3C3B6E]/5 border border-[#3C3B6E]/10 rounded p-3 text-xs text-gray-600 flex gap-2", children: [ 1812 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-4 h-4 shrink-0 mt-0.5 text-[#3C3B6E]" }), 1813 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Commission statements are reviewed and approved by Greg before payment is released. Contact Greg with any questions about your statement." }) 1814 ] }) 1815 ] }) }), 1816 /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "transactions", className: "mt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [
1817 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-[#3C3B6E] text-white", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 1818 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Account" }), 1819 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Policy #" }), 1820 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Carrier" }), 1821 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "LOB" }), 1822 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Type" }), 1823 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-right", children: "Commission" }), 1824 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-left", children: "Agent" }), 1825 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Dup" }),
1826 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-2 text-center", children: "Adj" }) 1827 ] }) }), 1828 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: txns.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("tr", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("td", { colSpan: 9, className: "p-6 text-center text-gray-400", children: 'No transactions yet. Click "Add Transactions" to begin.' }) }) : txns.map((t) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: `border-b border-gray-100 hover:bg-gray-50 ${t.isDuplicate ? "opacity-50 bg-red-50" : ""}`, children: [ 1829 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: t.accountName ?? "â" }), 1830 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 font-mono text-xs", children: t.policyNumber ?? "â" }), 1831 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: t.carrier ?? "â" }), 1832 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: t.lineOfBusiness ?? "â" }),
1833 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2", children: t.transactionType ?? "â" }), 1834 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-right font-medium text-green-700", children: fmtCurrency(t.commissionEarned) }), 1835 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-xs text-gray-600", children: t.assignedAgentKey ?? "â" }), 1836 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-center", children: t.isDuplicate ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "â" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-300", children: "â" }) }), 1837 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-2 text-center", children: t.isAdjustment ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-500", children: "â" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-300", children: "â" }) }) 1838 ] }, t.id)) }) 1839 ] }) }) }),
1840 /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "splits", className: "mt-4", children: !splits || splits.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12 text-gray-400", children: [ 1841 /* @__PURE__ */ jsxRuntimeExports.jsx(Calculator, { className: "w-12 h-12 mx-auto mb-3 opacity-30" }), 1842 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "No splits calculated yet." }), 1843 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: 'Add transactions first, then click "Calculate Splits".' }) 1844 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ 1845 splits.filter((s) => s.lineType !== "zach_override").map((split) => /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border border-gray-200", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-4", children: [ 1846 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
1847 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1848 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-[#3C3B6E]", children: split.agentName }) }), 1849 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: `${split.agentKey} · ${split.transactionCount} transactions · ${fmtPct(split.splitPct)} eff. rate` }) 1850 ] }), 1851 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-right flex flex-col items-end gap-2", children: [ 1852 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1853 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-[#B22234]", children: fmtCurrency(split.grandTotal) }), 1854 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Grand Total Due" }) 1855 ] }),
1856 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1.5", children: [ 1857 /* @__PURE__ */ jsxRuntimeExports.jsxs( 1858 Button, 1859 { 1860 variant: "outline", 1861 size: "sm", 1862 onClick: () => exportAgentStatement.mutate({ statementId, agentId: split.agentId }), 1863 disabled: exportAgentStatement.isPending || isPdfGenerating, 1864 className: "gap-1 border-green-600 text-green-700 hover:bg-green-600 hover:text-white text-xs", 1865 title: `Download Excel proof-of-work for ${split.agentName}`, 1866 children: [ 1867 exportAgentStatement.isPending && exportAgentStatement.variables?.agentId === split.agentId ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "w-3 h-3" }), 1868 "Excel" 1869 ] 1870 } 1871 ),
1872 /* @__PURE__ */ jsxRuntimeExports.jsxs( 1873 Button, 1874 { 1875 variant: "outline", 1876 size: "sm", 1877 onClick: () => downloadAgentPDF(split.agentId), 1878 disabled: exportAgentStatement.isPending || isPdfGenerating, 1879 className: "gap-1 border-red-600 text-red-700 hover:bg-red-600 hover:text-white text-xs", 1880 title: `Download PDF statement for ${split.agentName}`, 1881 children: [ 1882 isPdfGenerating ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileDown, { className: "w-3 h-3" }), 1883 "PDF" 1884 ] 1885 } 1886 ) 1887 ] }) 1888 ] }) 1889 ] }), 1890 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3 text-sm lg:grid-cols-5", children: [ 1891 /* @__P
1891URE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 rounded p-2", children: [ 1892 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Total Earned" }), 1893 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold", children: fmtCurrency(split.totalEarned) }) 1894 ] }), 1895 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 rounded p-2", children: [ 1896 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500", title: "Effective blended rate across standard (70%/80%/90%) and master-company (80%/100%) transactions", children: [ 1897 "Agent Due (eff. ", 1898 fmtPct(split.splitPct), 1899 ")" 1900 ] }), 1901 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-green-700", children: fmtCurrency(split.agentDue) }) 1902 ] }), 1903 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 rounded p-2", children: [
1904 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-600", children: "Profit Sharing" }), 1905 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-amber-700", children: fmtCurrency(split.profitSharing) }) 1906 ] }), 1907 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 rounded p-2", children: [ 1908 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-600", children: "Balance Adjustment" }), 1909 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `font-semibold ${parseFloat(split.balanceAdjustment) < 0 ? "text-red-600" : "text-blue-700"}`, children: fmtCurrency(split.balanceAdjustment) }) 1910 ] }), 1911 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-purple-50 rounded p-2", children: [ 1912 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-purple-600", children: "Commission Adjustments" }), 1913 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `font-semibold ${(adjustmentTotalsByAgent.get(split.agentId) ?? 0) < 0 ? "text-red-700" : "text-purple-700"}`, children: fmtCurrency(adjustmentTotalsByAgent.get(split.agentId) ?? 0) }),
1914 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-[10px] text-purple-600", children: "Included in Grand Total Due" }) 1915 ] }) 1916 ] }) 1917 ] }) }, split.id)), 1918 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-[#3C3B6E] text-white rounded-lg p-4 flex justify-between items-center", children: [ 1919 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1920 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm opacity-80", children: "Total Paid to Sub-Agents" }), 1921 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs opacity-60", children: "Pending owner approval before release" }) 1922 ] }), 1923 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-3xl font-bold text-[#B22234]", children: fmtCurrency(splits.reduce((s, sp) => s + parseFloat(sp.grandTotal || "0"), 0)) }) 1924 ] }), 1925 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 border border-amber-200 rounded p-3 text-xs text-amber-800 flex gap-2", children: [
1926 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-4 h-4 shrink-0 mt-0.5" }), 1927 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 1928 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Owner Approval Required." }), 1929 " Per EPS commission policy, final statements and payment instructions must be reviewed and approved by Greg before release. Commission information is confidential and must not appear in any client-facing communication." 1930 ] }) 1931 ] }) 1932 ] }) }), 1933 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "adjustments", className: "mt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ 1934 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border border-[#3C3B6E]/20", children: [ 1935 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { className: "pb-3", children: [ 1936 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm text-[#3C3B6E] flex items-center gap-2", children: [
1937 /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "w-4 h-4" }), 1938 " AI Adjustment Assistant" 1939 ] }), 1940 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Describe a commission issue and the AI will suggest the correct adjustment amount and type." }) 1941 ] }), 1942 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [ 1943 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1944 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Agent" }), 1945 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: adjAgentId, onValueChange: setAdjAgentId, children: [ 1946 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-8 text-xs mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select agentâ¦" }) }),
1947 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: AGENT_SPLIT_RULES.map((a) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: a.id, children: a.name }, a.id)) }) 1948 ] }) 1949 ] }) }), 1950 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1951 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Describe the issue" }), 1952 /* @__PURE__ */ jsxRuntimeExports.jsx( 1953 Textarea, 1954 { 1955 className: "mt-1 text-xs min-h-[80px]", 1956 placeholder: "e.g. Josh's Nationwide policy #ABC123 was not included in this statement. The commission was $245.00. Also, the Celina policy #XYZ was paid twice last period â deduct $180.00.", 1957 value: adjMessage, 1958 onChange: (e) => setAdjMessage(e.target.value) 1959 } 1960 ) 1961 ] }), 1962 /* @__PURE__ */ jsxRuntimeExports.jsx( 1963 Button, 1964 { 1965 size: "sm", 1966 onClick: () => { 1967 if (!adjAgentId) { 1968 toast.error("Select an agent first"); 1969 return; 1970 } 1971 if (!adjMessage.trim()) { 1972 toast.error("Describe the issue first"); 1973 return; 1974 } 1975 aiSuggest.mutate({ statementId, agentId: adjAgentId, agentName: selectedAgentName, userMessage: adjMessage }); 1976 }, 1977 disabled: aiSuggest.isPending, 1978 className: "gap-2 bg-[#3C3B6E] hover:bg-[#3C3B6E]/80 text-white",
1979 children: aiSuggest.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1980 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }), 1981 " Analyzingâ¦" 1982 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1983 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-3 h-3" }), 1984 " Get AI Suggestions" 1985 ] }) 1986 } 1987 ), 1988 aiSuggestions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 pt-2", children: [ 1989 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-[#3C3B6E]", children: "AI Suggestions â review and apply:" }), 1990 aiSuggestions.map((s, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `rounded border p-3 text-xs space-y-1 ${s.type === "deduct" ? "border-red-200 bg-red-50" : s.type === "bonus" ? "border-amber-200 bg-amber-50" : "border-green-200 bg-green-50"}`, children: [
1991 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 1992 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 font-semibold", children: [ 1993 s.type === "deduct" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircleMinus, { className: "w-3 h-3 text-red-600" }) : s.type === "bonus" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Gift, { className: "w-3 h-3 text-amber-600" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CirclePlus, { className: "w-3 h-3 text-green-600" }), 1994 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: s.type === "deduct" ? "text-red-700" : s.type === "bonus" ? "text-amber-700" : "text-green-700", children: [ 1995 s.type === "deduct" ? "Deduct" : s.type === "bonus" ? "Bonus" : "Add", 1996 " ", 1997 fmtCurrency(s.amount) 1998 ] }) 1999 ] }), 2000 /* @__PURE__ */ jsxRuntimeExports.jsx( 2001 Button, 2002 { 2003 size: "sm", 2004 variant: "outline", 2005 className: "h-6 text-xs px-2 border-[#3C3B6E] text-[#3C3B6E]", 2006 disabled: addAdj.isPending, 2007 onClick: () => setAdjConfirm({ 2008 statementId, 2009 agentId: adjAgentId, 2010 agentName: selectedAgentName, 2011 type: s.type, 2012 amount: s.amount, 2013 description: s.description, 2014 policyNumber: s.policyNumber ?? void 0, 2015 carrier: s.carrier ?? void 0, 2016 aiSuggested: true, 2017 aiReasoning: s.reasoning 2018 }), 2019 children: "Apply" 2020 } 2021 ) 2022 ] }),
2023 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-700", children: s.description }), 2024 s.policyNumber && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-gray-500", children: [ 2025 "Policy: ", 2026 s.policyNumber, 2027 s.carrier ? ` · ${s.carrier}` : "" 2028 ] }), 2029 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-gray-500 italic", children: [ 2030 "AI reasoning: ", 2031 s.reasoning 2032 ] }) 2033 ] }, i)) 2034 ] }) 2035 ] }) 2036 ] }), 2037 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border border-gray-200", children: [ 2038 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { className: "pb-3", children: [ 2039 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm text-[#3C3B6E] flex items-center gap-2", children: [ 2040 /* @__PURE__ */ jsxRuntimeExports.jsx(CirclePlus, { className: "w-4 h-4" }), 2041 " Manual Adjustment" 2042 ] }),
2043 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Add a correction directly without AI assistance." }) 2044 ] }), 2045 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [ 2046 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [ 2047 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2048 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Agent" }), 2049 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: adjAgentId, onValueChange: setAdjAgentId, children: [ 2050 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-8 text-xs mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select agentâ¦" }) }), 2051 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: AGENT_SPLIT_RULES.map((a) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: a.id, children: a.name }, a.id)) }) 2052 ] }) 2053 ] }),
2054 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2055 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Type" }), 2056 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: manualType, onValueChange: (v) => setManualType(v), children: [ 2057 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-8 text-xs mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }), 2058 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 2059 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "add", children: "Add (missed commission)" }), 2060 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "deduct", children: "Deduct (overpayment)" }), 2061 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "bonus", children: "Bonus (discretionary)" }) 2062 ] }) 2063 ] }) 2064 ] }), 2065 /* @__P
2065URE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2066 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Amount ($)" }), 2067 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { className: "h-8 text-xs mt-1", type: "number", min: "0.01", step: "0.01", placeholder: "0.00", value: manualAmount, onChange: (e) => setManualAmount(e.target.value) }) 2068 ] }), 2069 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2070 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Policy # (optional)" }), 2071 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { className: "h-8 text-xs mt-1", placeholder: "e.g. ABC123", value: manualPolicy, onChange: (e) => setManualPolicy(e.target.value) }) 2072 ] }), 2073 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2074 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Carrier (optional)" }), 2075 /* @__P
2075URE__ */ jsxRuntimeExports.jsx(Input, { className: "h-8 text-xs mt-1", placeholder: "e.g. Nationwide", value: manualCarrier, onChange: (e) => setManualCarrier(e.target.value) }) 2076 ] }) 2077 ] }), 2078 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2079 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Description" }), 2080 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { className: "h-8 text-xs mt-1", placeholder: "Brief reason for this adjustment", value: manualDesc, onChange: (e) => setManualDesc(e.target.value) }) 2081 ] }), 2082 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2083 Button, 2084 { 2085 size: "sm", 2086 disabled: addAdj.isPending, 2087 onClick: () => { 2088 if (!adjAgentId) { 2089 toast.error("Select an agent"); 2090 return; 2091 } 2092 const amt = parseFloat(manualAmount); 2093 if (!amt || amt <= 0) { 2094 toast.error("Enter a valid amount"); 2095 return; 2096 } 2097 if (!manualDesc.trim()) { 2098 toast.error("Enter a description"); 2099 return; 2100 } 2101 setAdjConfirm({ 2102 statementId, 2103 agentId: adjAgentId, 2104 agentName: selectedAgentName, 2105 type: manualType, 2106 amount: amt, 2107 description: manualDesc, 2108 policyNumber: manualPolicy || void 0, 2109 carrier: manualCarrier || void 0, 2110 aiSuggested: false 2111 }); 2112 }, 2113 className: "gap-2 bg-[#3C3B6E] hover:bg-[#3C3B6E]/80 text-white", 2114 children: [
2115 addAdj.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-3 h-3" }), 2116 "Add Adjustment" 2117 ] 2118 } 2119 ) 2120 ] }) 2121 ] }), 2122 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "border border-gray-200", children: [ 2123 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm text-[#3C3B6E]", children: [ 2124 "Applied Adjustments (", 2125 adjustments?.length ?? 0, 2126 ")" 2127 ] }) }), 2128 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: !adjustments || adjustments.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 text-center py-4", children: "No adjustments applied yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ 2129 adjustments.map((adj) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex items-start justify-between rounded border p-3 text-xs ${adj.type === "deduct" ? "border-red-200 bg-red-50" : adj.type === "bonus" ? "border-amber-200 bg-amber-50" : "border-green-200 bg-green-50"}`, children: [
2130 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-0.5", children: [ 2131 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 font-semibold", children: [ 2132 adj.type === "deduct" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircleMinus, { className: "w-3 h-3 text-red-600" }) : adj.type === "bonus" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Gift, { className: "w-3 h-3 text-amber-600" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CirclePlus, { className: "w-3 h-3 text-green-600" }), 2133 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: adj.type === "deduct" ? "text-red-700" : adj.type === "bonus" ? "text-amber-700" : "text-green-700", children: [ 2134 adj.type === "deduct" ? "Deduct" : adj.type === "bonus" ? "Bonus" : "Add", 2135 " ", 2136 fmtCurrency(adj.amount), 2137 " â ", 2138 adj.agentName 2139 ] }), 2140 adj.aiSuggested && /* @__P
2140URE__ */ jsxRuntimeExports.jsx("span", { className: "bg-purple-100 text-purple-700 px-1 rounded", children: "AI" }) 2141 ] }), 2142 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-700", children: adj.description }), 2143 adj.policyNumber && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-gray-500", children: [ 2144 "Policy: ", 2145 adj.policyNumber, 2146 adj.carrier ? ` · ${adj.carrier}` : "" 2147 ] }) 2148 ] }), 2149 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [ 2150 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2151 Button, 2152 { 2153 variant: "outline", 2154 size: "sm", 2155 className: "h-7 gap-1 border-[#3C3B6E]/30 px-2 text-[11px] text-[#3C3B6E]", 2156 disabled: previewNotification.isPending, 2157 onClick: () => previewNotification.mutate({ 2158 statementId, 2159 changeType: "adjustment_added", 2160 changeId: adj.id, 2161 description: `${adj.type === "deduct" ? "Deduction" : adj.type === "bonus" ? "Bonus" : "Adjustment"}: ${adj.description} ($${Number(adj.amount).toFixed(2)})`, 2162 affectedAgentIds: [adj.agentId] 2163 }), 2164 children: [
2165 /* @__PURE__ */ jsxRuntimeExports.jsx(Mail, { className: "h-3 w-3" }), 2166 " Preview Email" 2167 ] 2168 } 2169 ), 2170 /* @__PURE__ */ jsxRuntimeExports.jsx( 2171 Button, 2172 { 2173 variant: "ghost", 2174 size: "sm", 2175 className: "h-7 w-7 p-0 text-red-500 hover:text-red-700 hover:bg-red-50", 2176 disabled: removeAdj.isPending, 2177 onClick: () => removeAdj.mutate({ adjustmentId: adj.id }), 2178 title: "Remove adjustment", 2179 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-3 h-3" }) 2180 } 2181 ) 2182 ] }) 2183 ] }, adj.id)), 2184 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-[#3C3B6E] text-white rounded p-3 flex justify-between items-center text-sm", children: [ 2185 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: "Net Adjustment Total" }),
2186 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-bold text-[#B22234]", children: fmtCurrency(adjustments.reduce((s, a) => s + (a.type === "deduct" ? -parseFloat(a.amount) : parseFloat(a.amount)), 0)) }) 2187 ] }) 2188 ] }) }) 2189 ] }), 2190 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 border border-amber-200 rounded p-3 text-xs text-amber-800 flex gap-2", children: [ 2191 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-4 h-4 shrink-0 mt-0.5" }), 2192 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 2193 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Notification safety:" }), 2194 " Adjustments update reconciled totals immediately, but producer email is not sent until an administrator reviews the exact recipients and message, then selects ", 2195 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Confirm & Send" }), 2196 "." 2197 ] }) 2198 ] }) 2199 ] }) }) 2200 ] }), 2201 adjConfirm && (() => { 2202 const agentSplit = (splits ?? []).find((s) => s.agentId === adjConfirm.agentId); 2203 const currentBase = agentSplit ? Number(agentSplit.agentDue ?? 0) + Number(agentSplit.profitSharing ?? 0) + Number(agentSplit.balanceAdjustment ?? 0) : 0; 2204 const existingAdj = (adjustments ?? []).reduce((sum, a) => sum + (a.type === "deduct" ? -Number(a.amount) : Number(a.amount)), 0); 2205 const thisAdj = adjConfirm.type === "deduct" ? -adjConfirm.amount : adjConfirm.amount; 2206 const newGrandTotal = currentBase + existingAdj + thisAdj; 2207 const typeLabel = adjConfirm.type === "deduct" ? "Deduction" : adjConfirm.type === "bonus" ? "Bonus" : "Addition"; 2208 const typeColor = adjConfirm.type === "deduct" ? "text-red-600" : adjConfirm.type === "bonus" ? "text-amber-600" : "text-green-600"; 2209 const typeBg = adjConfirm.type === "deduct" ? "bg-red-50 border-red-200" : adjConfirm.type === "bonus" ? "bg-amber-50 border-amber-200" : "bg-green-50 border-green-200"; 2210 return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: true, onOpenChange: () => setAdjConfirm(null), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-md", children: [
2211 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 2212 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { className: "text-[#3C3B6E]", children: "Confirm Adjustment" }), 2213 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Review the adjustment details before saving." }) 2214 ] }), 2215 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 py-2", children: [ 2216 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `rounded border p-4 text-sm space-y-2 ${typeBg}`, children: [ 2217 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2218 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-700", children: "Agent" }), 2219 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-bold text-[#3C3B6E]", children: adjConfirm.agentName }) 2220 ] }), 2221 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
2222 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-700", children: "Type" }), 2223 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `font-bold ${typeColor}`, children: typeLabel }) 2224 ] }), 2225 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2226 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-700", children: "Amount" }), 2227 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: `font-bold text-lg ${typeColor}`, children: [ 2228 adjConfirm.type === "deduct" ? "-" : "+", 2229 fmtCurrency(adjConfirm.amount) 2230 ] }) 2231 ] }), 2232 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2233 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-700", children: "Description" }),
2234 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-800 text-right max-w-[60%]", children: adjConfirm.description }) 2235 ] }), 2236 adjConfirm.carrier && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2237 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-700", children: "Carrier" }), 2238 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-800", children: adjConfirm.carrier }) 2239 ] }), 2240 adjConfirm.policyNumber && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2241 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-700", children: "Policy #" }), 2242 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-800", children: adjConfirm.policyNumber }) 2243 ] }) 2244 ] }), 2245 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-[#3C3B6E]/20 bg-[#3C3B6E]/5 p-4 text-sm space-y-2", children: [
2246 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-[#3C3B6E] uppercase tracking-wide", children: "Grand Total Impact" }), 2247 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2248 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600", children: "Current Grand Total" }), 2249 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: fmtCurrency(currentBase + existingAdj) }) 2250 ] }), 2251 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2252 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600", children: "This Adjustment" }), 2253 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: `font-semibold ${typeColor}`, children: [ 2254 adjConfirm.type === "deduct" ? "-" : "+", 2255 fmtCurrency(adjConfirm.amount) 2256 ] }) 2257 ] }),
2258 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-[#3C3B6E]/20 pt-2 flex items-center justify-between", children: [ 2259 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-bold text-[#3C3B6E]", children: "New Grand Total" }), 2260 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-bold text-lg text-[#3C3B6E]", children: fmtCurrency(newGrandTotal) }) 2261 ] }) 2262 ] }) 2263 ] }), 2264 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { className: "gap-2", children: [ 2265 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setAdjConfirm(null), children: "Cancel" }), 2266 /* @__PURE__ */ jsxRuntimeExports.jsx( 2267 Button, 2268 { 2269 className: "bg-[#3C3B6E] hover:bg-[#3C3B6E]/80 text-white", 2270 disabled: addAdj.isPending, 2271 onClick: () => addAdj.mutate(adjConfirm), 2272 children: addAdj.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2273 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3 h-3 animate-spin" }), 2274 " Savingâ¦" 2275 ] }) : "Confirm & Save" 2276 } 2277 ) 2278 ] }) 2279 ] }) }); 2280 })(), 2281 notificationPreview && /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: true, onOpenChange: () => setNotificationPreview(null), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-3xl max-h-[88vh] overflow-y-auto", children: [ 2282 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 2283 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2 text-[#3C3B6E]", children: [ 2284 /* @__PURE__ */ jsxRuntimeExports.jsx(Mail, { className: "h-5 w-5" }), 2285 " Preview Commission Notification" 2286 ] }), 2287 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "No email has been sent. Verify every recipient and the complete message before confirming delivery." }) 2288 ] }),
2289 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 py-2", children: [ 2290 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [ 2291 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: "bg-[#3C3B6E] text-white", children: notificationPreview.scope === "affected_producer_groups" ? "Affected producer only" : "Statement-wide" }), 2292 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", children: [ 2293 notificationPreview.groupCount, 2294 " group", 2295 notificationPreview.groupCount === 1 ? "" : "s" 2296 ] }), 2297 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", children: [ 2298 notificationPreview.recipientCount, 2299 " recipient", 2300 notificationPreview.recipientCount === 1 ? "" : "s" 2301 ] }), 2302 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", children: [ 2303 "Period ", 2304 notificationPreview.period 2305 ] }) 2306 ] }),
2307 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-y border-gray-200 py-3", children: [ 2308 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-bold uppercase tracking-wide text-gray-500", children: "Exact Recipients" }), 2309 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 space-y-3", children: notificationPreview.deliveries.map((delivery) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2 border-b border-gray-100 pb-3 last:border-b-0 last:pb-0 md:grid-cols-[160px_1fr]", children: [ 2310 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2311 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-[#3C3B6E]", children: delivery.groupLabel }), 2312 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-xs font-medium ${delivery.status === "ready" ? "text-green-700" : delivery.status === "already_sent" ? "text-gray-600" : "text-red-700"}`, children: delivery.status === "ready" ? "Ready to send" : delivery.status === "already_sent" ? "Already sent" : "Blocked" }) 2313 ] }),
2314 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1 text-sm", children: [ 2315 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [ 2316 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-600", children: "To:" }), 2317 " ", 2318 delivery.to ? `${delivery.to.agentName} <${delivery.to.email}>` : "No active primary email" 2319 ] }), 2320 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [ 2321 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-gray-600", children: "CC:" }), 2322 " ", 2323 delivery.cc.length ? delivery.cc.map((recipient) => `${recipient.agentName} <${recipient.email}>`).join(", ") : "None" 2324 ] }), 2325 delivery.warning && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-medium text-red-700", children: delivery.warning }) 2326 ] }) 2327 ] }, delivery.groupId)) }) 2328 ] }),
2329 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2 rounded border border-gray-200 bg-gray-50 p-3 text-xs sm:grid-cols-4", children: [ 2330 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2331 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Downloaded" }), 2332 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold", children: fmtCurrency(notificationPreview.snapshot.downloadedSubtotal) }) 2333 ] }), 2334 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2335 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Manual" }), 2336 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold", children: fmtCurrency(notificationPreview.snapshot.manualSubtotal) }) 2337 ] }), 2338 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2339 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Adjustments" }),
2340 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold", children: fmtCurrency(notificationPreview.snapshot.adjustmentSubtotal) }) 2341 ] }), 2342 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2343 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Agency Due" }), 2344 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-bold text-[#3C3B6E]", children: fmtCurrency(notificationPreview.snapshot.agencyGrandTotalDue) }) 2345 ] }) 2346 ] }), 2347 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ 2348 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-bold uppercase tracking-wide text-gray-500", children: "Email Preview" }), 2349 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-gray-200 bg-white p-3", children: [ 2350 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "Subject" }),
2351 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-gray-900", children: notificationPreview.subject }), 2352 /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-3 max-h-56 overflow-y-auto whitespace-pre-wrap border-t border-gray-100 pt-3 font-sans text-sm text-gray-700", children: notificationPreview.deliveries[0]?.text }) 2353 ] }) 2354 ] }), 2355 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-amber-200 bg-amber-50 p-3", children: [ 2356 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-bold uppercase tracking-wide text-amber-800", children: "Excluded from commission email" }), 2357 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-amber-900", children: notificationPreview.excludedRecipients.map((recipient) => `${recipient.agentName} â ${recipient.reason}`).join("; ") || "No restricted accounts found." }) 2358 ] }) 2359 ] }), 2360 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { className: "gap-2", children: [
2361 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setNotificationPreview(null), children: "Cancel â Do Not Send" }), 2362 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2363 Button, 2364 { 2365 className: "gap-2 bg-[#B22234] text-white hover:bg-[#8f1b2a]", 2366 disabled: sendPreviewedNotification.isPending || notificationPreview.deliveries.some((delivery) => delivery.status === "blocked") || notificationPreview.groupCount === 0, 2367 onClick: () => sendPreviewedNotification.mutate({ 2368 statementId: notificationPreview.statementId, 2369 changeType: notificationPreview.changeType, 2370 changeId: notificationPreview.changeId, 2371 description: notificationPreview.description, 2372 affectedAgentIds: notificationPreview.affectedAgentIds, 2373 expectedPreviewFingerprint: notificationPreview.fingerprint 2374 }), 2375 children: [ 2376 sendPreviewedNotification.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), 2377 "Confirm & Send Email", 2378 notificationPreview.groupCount === 1 ? "" : "s" 2379 ] 2380 } 2381 ) 2382 ] }) 2383 ] }) }) 2384 ] }); 2385} 2386function AgentYTDSummary() { 2387 const year = (/* @__PURE__ */ new Date()).getFullYear(); 2388 const { data: rows, isLoading } = trpc.commissions.getAgentYTDEarnings.useQuery({ year }); 2389 if (isLoading) return /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-4 flex items-center gap-2 text-sm text-gray-400", children: [ 2390 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }), 2391 " Loading YTD earningsâ¦" 2392 ] }) }); 2393 if (!rows || rows.length === 0) return null; 2394 const totalGrand = rows.reduce((s, r) => s + parseFloat(r.grandTotal || "0"), 0); 2395 return /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ 2396 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { className: "pb-2", children: [
2397 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm text-[#3C3B6E] flex items-center gap-2", children: [ 2398 /* @__PURE__ */ jsxRuntimeExports.jsx(TrendingUp, { className: "w-4 h-4" }), 2399 " ", 2400 year, 2401 " YTD Agent Earnings" 2402 ] }), 2403 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [ 2404 "One reconciled row per producer across all finalized ", 2405 year, 2406 " statement periods." 2407 ] }) 2408 ] }), 2409 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [ 2410 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full min-w-[920px] text-sm", children: [ 2411 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-gray-200 text-xs text-gray-500 uppercase", children: [ 2412 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-left whitespace-nowrap", children: "Agent" }),
2413 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-right whitespace-nowrap", children: "Agency Earned" }), 2414 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-right whitespace-nowrap", children: "Agent Due" }), 2415 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-right whitespace-nowrap", children: "Profit Sharing" }), 2416 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-right whitespace-nowrap", children: "Adjustments" }), 2417 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-right font-bold whitespace-nowrap", children: "Grand Total" }), 2418 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-center", children: "Stmts" }), 2419 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 pb-2 text-center", children: "Txns" }) 2420 ] }) }), 2421 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: rows.map((r) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-gray-100 hover:bg-gray-50", children: [
2422 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 font-semibold text-[#3C3B6E] whitespace-nowrap", children: r.agentName }), 2423 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-right text-gray-600", children: fmtCurrency(r.totalEarned) }), 2424 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-right text-gray-600", children: fmtCurrency(r.agentDue) }), 2425 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-right text-amber-600", children: parseFloat(r.profitSharing) > 0 ? fmtCurrency(r.profitSharing) : "â" }), 2426 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-right text-gray-500", children: parseFloat(r.balanceAdj) !== 0 ? fmtCurrency(r.balanceAdj) : "â" }), 2427 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-right font-bold text-[#B22234]", children: fmtCurrency(r.grandTotal) }), 2428 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-center text-gray-500", children: r.statementCount }),
2429 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2.5 text-center text-gray-500", children: r.txCount }) 2430 ] }, r.agentId)) }), 2431 /* @__PURE__ */ jsxRuntimeExports.jsx("tfoot", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t-2 border-[#3C3B6E]/20 bg-[#3C3B6E]/5", children: [ 2432 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 font-bold text-[#3C3B6E]", children: "Total" }), 2433 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { colSpan: 4 }), 2434 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right font-bold text-[#3C3B6E]", children: fmtCurrency(totalGrand) }), 2435 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { colSpan: 2 }) 2436 ] }) }) 2437 ] }) }), 2438 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 mt-2", children: "Legacy and current agent IDs are consolidated. Override compensation is included in Agent Due and Grand Total without double-counting agency transactions." }) 2439 ] }) 2440 ] }); 2441} 2442function CommissionsPanel() { 2443 const { user, isAuthenticated, loading } = useAuth(); 2444 const { agent: agentSession, isAuthenticated: isAgentAuthenticated, isAgentAdmin } = useAgentAuth(); 2445 const [location, navigate] = useLocation(); 2446 location.startsWith("/agent"); 2447 const [localAgentSession] = reactExports.useState(() => { 2448 try { 2449 const raw = localStorage.getItem("eps_agent_session"); 2450 return raw ? JSON.parse(raw) : null; 2451 } catch { 2452 return null; 2453 } 2454 }); 2455 const authenticated = isAuthenticated || isAgentAuthenticated || Boolean(localAgentSession); 2456 const resolvedAgentKey = agentSession?.agentKey ?? localAgentSession?.agentKey; 2457 const deniedSections = /* @__PURE__ */ new Set([ 2458 ...localAgentSession?.deniedSections ?? [], 2459 ...agentSession?.deniedSections ?? [] 2460 ]); 2461 const commissionAccessDenied = resolvedAgentKey === "kiara-mateo" || user?.email?.trim().toLowerCase() === "[email protected]" || deniedSections.has("/commissions") || deniedSections.has("/agent/commissions"); 2462 const authLoading = loading && !localAgentSession; 2463 const isAdmin = !commissionAccessDenied && (isAuthenticated || (agentSession ? isAgentAdmin : localAgentSession?.isAdmin === true)); 2464 const [selectedStatement, setSelectedStatement] = reactExports.useState(null); 2465 const [confirmDeleteId, setConfirmDeleteId] = reactExports.useState(null); 2466 const [addFilePeriod, setAddFilePeriod] = reactExports.useState(null); 2467 const [mergeDialogOpen, setMergeDialogOpen] = reactExports.useState(false); 2468 const [mergePeriod, setMergePeriod] = reactExports.useState(null); 2469 const [mergePrimaryId, setMergePrimaryId] = reactExports.useState(null); 2470 const [mergeReport, setMergeReport] = reactExports.useState(null); 2471 const [dateFrom, setDateFrom] = reactExports.useState(""); 2472 const [dateTo, setDateTo] = reactExports.useState(""); 2473 const { data: stmtData, refetch: refetchStmts } = trpc.commissions.listStatements.useQuery( 2474 { dateFrom: dateFrom || void 0, dateTo: dateTo || void 0 }, 2475 { retry: false, enabled: authenticated && !commissionAccessDenied } 2476 ); 2477 const [newPeriodOpen, setNewPeriodOpen] = reactExports.useState(false); 2478 const [newPeriodMonth, setNewPeriodMonth] = reactExports.useState(() => { 2479 const d = /* @__PURE__ */ new Date(); 2480 d.setMonth(d.getMonth() + 1); 2481 return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`; 2482 }); 2483 const createStatement = trpc.commissions.createStatement.useMutation({ 2484 onSuccess: () => { 2485 toast.success(`Statement period ${newPeriodMonth} created`); 2486 setNewPeriodOpen(false); 2487 refetchStmts(); 2488 }, 2489 onError: (e) => toast.error(e.message) 2490 }); 2491 const { data: summary } = trpc.commissions.getSummary.useQuery(void 0, { 2492 retry: false, 2493 enabled: authenticated && !commissionAccessDenied 2494 }); 2495 const { data: historicalRateReference, refetch: refetchHistoricalRateReference } = trpc.commissions.getHistoricalRateReference.useQuery(void 0, { 2496 retry: false, 2497 enabled: authenticated && !commissionAccessDenied && resolvedAgentKey !== "ryan-fay" 2498 }); 2499 const [historicalRateSearchInput, setHistoricalRateSearchInput] = reactExports.useState(""); 2500 const [historicalRateSearchQuery, setHistoricalRateSearchQuery] = reactExports.useState(""); 2501 const historicalRateSearch = trpc.commissions.searchHistoricalRateReference.useQuery( 2502 { query: historicalRateSearchQuery, limit: 24 }, 2503 { 2504 retry: false, 2505 enabled: authenticated && !commissionAccessDenied && resolvedAgentKey !== "ryan-fay" && historicalRateSearchQuery.length >= 2 2506 } 2507 ); 2508 const downloadHistoricalRateReference = trpc.commissions.downloadHistoricalRateReference.useMutation({ 2509 onSuccess: (download) => { 2510 const anchor = document.createElement("a"); 2511 anchor.href = download.url; 2512 anchor.download = download.fileName; 2513 anchor.target = "_blank"; 2514 anchor.rel = "noopener noreferrer"; 2515 document.body.appendChild(anchor); 2516 anchor.click(); 2517 anchor.remove(); 2518 toast.success("Historical commission-rate workbook download started"); 2519 }, 2520 onError: (error) => toast.error(error.message) 2521 }); 2522 const refreshHistoricalRateReference = trpc.commissions.refreshHistoricalRateReference.useMutation({ 2523 onSuccess: async (result) => { 2524 await refetchHistoricalRateReference(); 2525 if (result.status === "failed") toast.error(`Workbook refresh failed: ${result.error}`); 2526 else toast.success(result.status === "unchanged" ? "Historical rate reference is already current" : "Historical rate reference refreshed"); 2527 }, 2528 onError: (error) => toast.error(error.message) 2529 }); 2530 const mergeStatements = trpc.commissions.mergeStatements.useMutation({ 2531 onSuccess: (d) => { 2532 setMergeDialogOpen(false); 2533 setMergePeriod(null); 2534 setMergePrimaryId(null); 2535 refetchStmts(); 2536 if (d.report) setMergeReport(d.report); 2537 }, 2538 onError: (e) => toast.error(e.message) 2539 }); 2540 const deleteStatement = trpc.commissions.deleteStatement.useMutation({ 2541 onSuccess: () => { 2542 toast.success("Statement deleted"); 2543 setConfirmDeleteId(null); 2544 refetchStmts(); 2545 }, 2546 onError: (e) => { 2547 toast.error(e.message); 2548 setConfirmDeleteId(null); 2549 } 2550 }); 2551 const chatMutation = trpc.commissions.chat.useMutation(); 2552 trpc.commissions.bulkRecalculate.useMutation({ 2553 onSuccess: (d) => { 2554 if (d.recalculated === 0) toast.info("All statements already have splits calculated."); 2555 else toast.success(`Splits recalculated for ${d.recalculated} statement${d.recalculated === 1 ? "" : "s"}.`); 2556 refetchStmts(); 2557 }, 2558 onError: (e) => toast.error(e.message) 2559 }); 2560 if (!authLoading && !authenticated) { 2561 return /* @__PURE__ */ jsxRuntimeExports.jsx(LoginPrompt, { title: "Login Required", description: "Sign in to access commission reports and statement data." }); 2562 } 2563 if (commissionAccessDenied) { 2564 return /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "mx-auto mt-12 max-w-xl border-red-200 bg-red-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "flex items-start gap-3 p-6", children: [
2565 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "mt-0.5 h-5 w-5 shrink-0 text-red-700" }), 2566 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2567 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "font-semibold text-red-900", children: "Commission access is not enabled" }), 2568 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm text-red-800", children: "This account cannot view commission statements, adjustments, reports, or performance-bonus information." }) 2569 ] }) 2570 ] }) }); 2571 } 2572 const AGENCY_SPLIT_ALIAS = { 2573 "emily-bucher": "jon-bucher", 2574 "angie-hinkle": "josh-hinkle" 2575 }; 2576 const currentAgentSplitId = agentSession?.agentKey ? AGENCY_SPLIT_ALIAS[agentSession.agentKey] ?? agentSession.agentKey : void 0; 2577 if (selectedStatement) { 2578 return /* @__PURE__ */ jsxRuntimeExports.jsx( 2579 StatementDetail, 2580 { 2581 statementId: selectedStatement.id, 2582 period: selectedStatement.period, 2583 isAdmin, 2584 agentId: currentAgentSplitId, 2585 onBack: () => { 2586 setSelectedStatement(null); 2587 refetchStmts(); 2588 } 2589 } 2590 ); 2591 } 2592 const statements = stmtData?.items ?? []; 2593 const periodGroups = statements.reduce((acc, s) => { 2594 if (!acc[s.period]) acc[s.period] = []; 2595 acc[s.period].push(s); 2596 return acc; 2597 }, {}); 2598 const periodsWithMultiple = new Set(Object.keys(periodGroups).filter((p) => periodGroups[p].length > 1)); 2599 const mergeGroup = mergePeriod ? (periodGroups[mergePeriod] ?? []).slice().sort((a, b) => a.id - b.id) : []; 2600 const effectivePrimaryId = mergePrimaryId ?? (mergeGroup[0]?.id ?? null); 2601 const secondaryIds = mergeGroup.filter((s) => s.id !== effectivePrimaryId).map((s) => s.id); 2602 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ 2603 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
2604 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2605 /* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-2xl font-bold text-[#3C3B6E]", children: [ 2606 /* @__PURE__ */ jsxRuntimeExports.jsx(USFlag, { size: 18 }), 2607 " ", 2608 isAdmin ? "Commissions Agent" : `My Commissions â ${agentSession?.agentName ?? ""}` 2609 ] }), 2610 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 text-sm mt-1", children: isAdmin ? "Monthly statement processing · Sub-agent splits · Profit Sharing · Owner-approved reporting" : "Your commission statements and split summaries" }) 2611 ] }), 2612 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2613 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", onClick: () => navigate("/commissions/settings"), className: "gap-1.5 text-[#3C3B6E] border-[#3C3B6E]/30", children: [ 2614 /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-3.5 h-3.5" }), 2615 " Split Settings" 2616 ] }),
2617 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs(Dialog, { open: newPeriodOpen, onOpenChange: setNewPeriodOpen, children: [ 2618 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", className: "gap-1.5 bg-[#3C3B6E] hover:bg-[#2d2c5a] text-white", children: [ 2619 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-3.5 h-3.5" }), 2620 " New Statement Period" 2621 ] }) }), 2622 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-sm", children: [ 2623 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 2624 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { className: "text-[#3C3B6E]", children: "Start New Commission Period" }), 2625 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Create an empty statement period. You can upload carrier files to it afterwards." }) 2626 ] }), 2627 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 py-2", children: [
2628 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2629 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium text-gray-700", children: "Period (YYYY-MM)" }), 2630 /* @__PURE__ */ jsxRuntimeExports.jsx( 2631 Input, 2632 { 2633 value: newPeriodMonth, 2634 onChange: (e) => setNewPeriodMonth(e.target.value), 2635 placeholder: "2026-06", 2636 className: "mt-1 font-mono" 2637 } 2638 ), 2639 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-1", children: "Format: YYYY-MM (e.g. 2026-06 for June 2026)" }) 2640 ] }), 2641 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1.5", children: Array.from({ length: 6 }, (_, i) => { 2642 const d = /* @__PURE__ */ new Date(); 2643 d.setMonth(d.getMonth() - 2 + i); 2644 const val = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`; 2645 const label = d.toLocaleString("default", { month: "short", year: "numeric" }); 2646 return /* @__PURE__ */ jsxRuntimeExports.jsx( 2647 "button", 2648 { 2649 onClick: () => setNewPeriodMonth(val), 2650 className: `px-2 py-1 text-xs rounded border transition-colors ${newPeriodMonth === val ? "bg-[#3C3B6E] text-white border-[#3C3B6E]" : "border-gray-200 text-gray-600 hover:border-[#3C3B6E]"}`, 2651 children: label 2652 }, 2653 val 2654 ); 2655 }) }) 2656 ] }),
2657 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 2658 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setNewPeriodOpen(false), children: "Cancel" }), 2659 /* @__PURE__ */ jsxRuntimeExports.jsx( 2660 Button, 2661 { 2662 className: "bg-[#3C3B6E] hover:bg-[#2d2c5a] text-white", 2663 disabled: !newPeriodMonth.match(/^\d{4}-\d{2}$/) || createStatement.isPending, 2664 onClick: () => createStatement.mutate({ period: newPeriodMonth, fileName: `${newPeriodMonth}-statement`, fileUrl: "" }), 2665 children: createStatement.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }) : "Create Period" 2666 } 2667 ) 2668 ] }) 2669 ] }) 2670 ] }), 2671 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(UploadStatementModal, { onSuccess: refetchStmts }), 2672 isAdmin && addFilePeriod && /* @__PURE__ */ jsxRuntimeExports.jsx( 2673 UploadStatementModal, 2674 { 2675 initialPeriod: addFilePeriod, 2676 forceOpen: !!addFilePeriod, 2677 onForceOpenChange: (v) => { 2678 if (!v) setAddFilePeriod(null); 2679 }, 2680 onSuccess: () => { 2681 setAddFilePeriod(null); 2682 refetchStmts(); 2683 } 2684 } 2685 ) 2686 ] }) 2687 ] }), 2688 resolvedAgentKey !== "ryan-fay" && /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border-2 border-[#3C3B6E]/35 bg-gradient-to-r from-[#3C3B6E]/5 via-white to-[#B22234]/5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-4 sm:p-5", children: [
2689 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between", children: [ 2690 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [ 2691 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md bg-[#3C3B6E] p-2.5 text-white", children: /* @__PURE__ */ jsxRuntimeExports.jsx(FileSpreadsheet, { className: "h-5 w-5" }) }), 2692 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ 2693 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [ 2694 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "font-semibold text-[#3C3B6E]", children: "Commission Rate Reference" }), 2695 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: "bg-[#B22234] text-white hover:bg-[#B22234]", children: "Pinned" }), 2696 historicalRateReference?.status === "ready" && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "border-green-300 bg-green-50 text-green-800", children: "Current" }), 2697 historicalRateReference?.status === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "border-red-300 bg-red-50 text-red-800", children: "Refresh issue" }) 2698 ] }), 2699 historicalRateReference ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2700 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1 text-sm text-gray-700", children: [ 2701 historicalRateReference.firstPeriod, 2702 "â", 2703 historicalRateReference.lastPeriod, 2704 " · ", 2705 historicalRateReference.normalizedCarrierCount.toLocaleString(), 2706 " historical carriers · ", 2707 historicalRateReference.combinationCount.toLocaleString(), 2708 " historical carrier/type combinations · ", 2709 historicalRateReference.knownRateRowCount.toLocaleString(), 2710 " paid-rate observations · ", 2711 historicalRateReference.officialScheduleEntryCount.toLocaleString(), 2712 " official schedule rows" 2713 ] }), 2714 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1 text-xs text-gray-500", children: [ 2715 "Automatically refreshed after committed commission changes and verified carrier schedule updates. Updated ", 2716 historicalRateReference.generatedAt ? new Date(historicalRateReference.generatedAt).toLocaleString() : "pending", 2717 "." 2718 ] }),
2719 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs font-medium text-[#7f1d1d]", children: historicalRateReference.disclaimer }), 2720 historicalRateReference.officialScheduleDisclaimer && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs font-medium text-[#7f1d1d]", children: historicalRateReference.officialScheduleDisclaimer }), 2721 historicalRateReference.lastError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 rounded-sm bg-amber-50 px-2 py-1.5 text-xs font-medium text-amber-900", children: "The latest automatic refresh failed; this download is the last verified workbook. An administrator can use Refresh Now to retry." }) 2722 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm text-gray-600", children: "The first historical-rate workbook is being prepared." }) 2723 ] }) 2724 ] }), 2725 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex shrink-0 flex-wrap gap-2 sm:flex-nowrap", children: [
2726 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs( 2727 Button, 2728 { 2729 variant: "outline", 2730 size: "sm", 2731 className: "gap-1.5 border-[#3C3B6E]/30 text-[#3C3B6E]", 2732 disabled: refreshHistoricalRateReference.isPending, 2733 onClick: () => refreshHistoricalRateReference.mutate(), 2734 children: [ 2735 refreshHistoricalRateReference.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "h-4 w-4" }), 2736 "Refresh Now" 2737 ] 2738 } 2739 ), 2740 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2741 Button, 2742 { 2743 size: "sm", 2744 className: "gap-1.5 bg-[#3C3B6E] text-white hover:bg-[#2d2c5a]", 2745 disabled: !historicalRateReference || historicalRateReference.status !== "ready" || downloadHistoricalRateReference.isPending, 2746 onClick: () => downloadHistoricalRateReference.mutate(), 2747 children: [ 2748 downloadHistoricalRateReference.isPending ? /* @__P
2748URE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "h-4 w-4" }), 2749 "Download Latest Excel" 2750 ] 2751 } 2752 ) 2753 ] }) 2754 ] }), 2755 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 border-t border-[#3C3B6E]/15 pt-4", children: [ 2756 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-3xl", children: [ 2757 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { htmlFor: "historical-carrier-rate-search", className: "text-sm font-semibold text-[#3C3B6E]", children: "Search commission rates by carrier" }), 2758 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2759 "form", 2760 { 2761 className: "mt-2 flex flex-col gap-2 sm:flex-row", 2762 onSubmit: (event) => { 2763 event.preventDefault(); 2764 const query = historicalRateSearchInput.trim(); 2765 if (query.length < 2) { 2766 toast.info("Enter at least two characters of a carrier name"); 2767 return; 2768 } 2769 setHistoricalRateSearchQuery(query); 2770 }, 2771 children: [
2772 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative min-w-0 flex-1", children: [ 2773 /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" }), 2774 /* @__PURE__ */ jsxRuntimeExports.jsx( 2775 Input, 2776 { 2777 id: "historical-carrier-rate-search", 2778 value: historicalRateSearchInput, 2779 onChange: (event) => { 2780 setHistoricalRateSearchInput(event.target.value); 2781 if (!event.target.value.trim()) setHistoricalRateSearchQuery(""); 2782 }, 2783 placeholder: "Search Acuity, Progressive, Bristol West, ASIâ¦", 2784 className: "pl-9", 2785 disabled: !historicalRateReference || historicalRateReference.status !== "ready" 2786 } 2787 ) 2788 ] }),
2789 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 2790 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2791 Button, 2792 { 2793 type: "submit", 2794 size: "sm", 2795 className: "min-w-24 gap-1.5 bg-[#B22234] text-white hover:bg-[#8f1b2a]", 2796 disabled: !historicalRateReference || historicalRateReference.status !== "ready" || historicalRateSearch.isFetching, 2797 children: [ 2798 historicalRateSearch.isFetching ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "h-4 w-4" }), 2799 "Search" 2800 ] 2801 } 2802 ), 2803 (historicalRateSearchInput || historicalRateSearchQuery) && /* @__PURE__ */ jsxRuntimeExports.jsx( 2804 Button, 2805 { 2806 type: "button", 2807 variant: "outline", 2808 size: "sm", 2809 onClick: () => { 2810 setHistoricalRateSearchInput(""); 2811 setHistoricalRateSearchQuery(""); 2812 }, 2813 children: "Clear" 2814 } 2815 ) 2816 ] }) 2817 ] 2818 } 2819 ),
2820 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500", children: "Search recognizes stored carrier names and supported aliases. Carrier-provided schedules and historical paid-rate evidence are displayed separately." }) 2821 ] }), 2822 historicalRateSearch.error && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800", children: [ 2823 "Rate search could not be completed: ", 2824 historicalRateSearch.error.message 2825 ] }), 2826 historicalRateSearchQuery.length >= 2 && historicalRateSearch.data && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4", children: [ 2827 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs text-gray-600", children: [ 2828 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 2829 historicalRateSearch.data.totalMatches.toLocaleString(), 2830 " result", 2831 historicalRateSearch.data.totalMatches === 1 ? "" : "s", 2832 " across ", 2833 historicalRateSearch.data.carrierCount.toLocaleString(), 2834 " carrier", 2835 historicalRateSearch.data.carrierCount === 1 ? "" : "s", 2836 " for â", 2837 historicalRateSearch.data.query, 2838 "â · ", 2839 historicalRateSearch.data.officialMatchCount.toLocaleString(), 2840 " official · ", 2841 historicalRateSearch.data.historicalMatchCount.toLocaleString(), 2842 " historical" 2843 ] }), 2844 historicalRateSearch.data.totalMatches >
2844 historicalRateSearch.data.results.length && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 2845 "Showing the first ", 2846 historicalRateSearch.data.results.length.toLocaleString(), 2847 " results" 2848 ] }) 2849 ] }), 2850 historicalRateSearch.data.results.length === 0 && historicalRateSearch.data.officialResults.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 rounded-md border border-dashed border-gray-300 bg-white/80 px-4 py-5 text-center", children: [ 2851 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-gray-700", children: [ 2852 "No verified commission rates found for â", 2853 historicalRateSearch.data.query, 2854 "â." 2855 ] }), 2856 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Try another carrier name or download the workbook to review official schedules and historical carrier labels." }) 2857 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 space-y-4", children: [ 2858 historicalRateSearch.data.officialResults.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-blue-200 bg-blue-50/50", children: [
2859 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-blue-200 px-3 py-2", children: [ 2860 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-blue-950", children: "Official carrier schedule" }), 2861 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-800", children: "Carrier-provided terms are shown separately from paid historical observations." }) 2862 ] }), 2863 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-[420px] overflow-y-auto", children: historicalRateSearch.data.officialResults.map((result) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-3 border-t border-blue-100 px-3 py-3 first:border-t-0 lg:grid-cols-[minmax(0,1fr)_minmax(260px,0.65fr)]", children: [ 2864 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ 2865 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
2866 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-900", children: result.carrier }), 2867 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: "bg-blue-700 text-white hover:bg-blue-700", children: "Official" }), 2868 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "border-blue-300 bg-white text-blue-900", children: [ 2869 "Effective ", 2870 result.effectiveDate 2871 ] }) 2872 ] }), 2873 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-2 text-sm text-gray-800", children: [ 2874 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: result.lineOfBusiness }), 2875 " â ", 2876 result.programOrCondition 2877 ] }), 2878 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1 text-xs text-gray-600", children: [ 2879 result.businessSegment, 2880 " · Jurisdiction: ", 2881 result.jurisdiction, 2882 " · Source: ", 2883 result.sourceFileName, 2884 " (", 2885 result.sourceForm, 2886 ")" 2887 ] }), 2888 result.sourceNote && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-2 text-xs font-medium text-amber-900", children: [ 2889 "Carrier note: ", 2890 result.sourceNote 2891 ] }) 2892 ] }),
2893 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [ 2894 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2895 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Base rate" }), 2896 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-lg font-bold text-[#B22234]", children: fmtRatePct(result.baseRate) }) 2897 ] }), 2898 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2899 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Service Center" }), 2900 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-lg font-bold text-[#3C3B6E]", children: fmtRatePct(result.serviceCenterRate) }) 2901 ] }) 2902 ] }) 2903 ] }, `${result.scheduleId}-${result.lineOfBusiness}-${result.programOrCondition}-${result.jurisdiction}`)) }),
2904 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "border-t border-blue-200 px-3 py-2 text-xs font-medium text-blue-950", children: historicalRateSearch.data.officialScheduleDisclaimer }) 2905 ] }), 2906 historicalRateSearch.data.results.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-[#3C3B6E]/15 bg-white/70", children: [ 2907 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-[#3C3B6E]/15 px-3 py-2", children: [ 2908 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-[#3C3B6E]", children: "Historical paid-rate evidence" }), 2909 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600", children: "Observed stored rates from prior EPS commission transactions." }) 2910 ] }), 2911 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-[560px] overflow-y-auto", children: historicalRateSearch.data.results.map((result) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-3 border-t border-gray-200 px-3 py-4 first:border-t-0 lg:grid-cols-[minmax(0,1fr)_minmax(360px,0.8fr)] lg:items-start", children: [
2912 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ 2913 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [ 2914 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-900", children: result.carrier }), 2915 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "border-[#3C3B6E]/25 text-[#3C3B6E]", children: result.transactionType }), 2916 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2917 Badge, 2918 { 2919 variant: "outline", 2920 className: result.confidence === "High" ? "border-green-300 bg-green-50 text-green-800" : result.confidence === "Medium" ? "border-amber-300 bg-amber-50 text-amber-900" : "border-red-300 bg-red-50 text-red-800", 2921 children: [ 2922 result.confidence, 2923 " confidence" 2924 ] 2925 } 2926 ) 2927 ] }),
2928 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-2 text-sm text-gray-700", children: [ 2929 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Observed distribution:" }), 2930 " ", 2931 result.distribution || "No stored distribution" 2932 ] }), 2933 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1 text-xs text-gray-600", children: [ 2934 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Periods:" }), 2935 " ", 2936 result.periods || "None" 2937 ] }), 2938 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1 text-xs text-gray-600", children: [ 2939 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Lines of business:" }), 2940 " ", 2941 result.lobs || "Not identified" 2942 ] }), 2943 result.reviewNote && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-2 text-xs font-medium text-amber-800", children: [ 2944 "Review: ", 2945 result.reviewNote 2946 ] }) 2947 ] }),
2948 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-x-4 gap-y-3 sm:grid-cols-3", children: [ 2949 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2950 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Primary rate" }), 2951 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-lg font-bold text-[#B22234]", children: fmtRatePct(result.primaryRate) }) 2952 ] }), 2953 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2954 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Weighted rate" }), 2955 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 font-semibold text-gray-900", children: fmtRatePct(result.premiumWeightedRate) }) 2956 ] }), 2957 /* @__P
2957URE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2958 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Average rate" }), 2959 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 font-semibold text-gray-900", children: fmtRatePct(result.averageRate) }) 2960 ] }), 2961 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2962 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Range" }), 2963 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-0.5 text-sm font-medium text-gray-800", children: [ 2964 fmtRatePct(result.minRate), 2965 "â", 2966 fmtRatePct(result.maxRate) 2967 ] }) 2968 ] }), 2969 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2970 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Samples" }), 2971 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-sm font-medium text-gray-800", children: result.evidenceCount.toLocaleString() }) 2972 ] }), 2973 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2974 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] font-medium uppercase tracking-wide text-gray-500", children: "Consistency" }), 2975 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-0.5 text-sm font-medium text-gray-800", children: result.consistency }) 2976 ] }) 2977 ] }) 2978 ] }, `${result.carrier}-${result.transactionType}`)) }), 2979 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "border-t border-[#3C3B6E]/15 px-3 py-2 text-xs font-medium text-[#7f1d1d]", children: historicalRateSearch.data.disclaimer }) 2980 ] }) 2981 ] }) 2982 ] }) 2983 ] }),
2984 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex items-center gap-2 border-t border-[#3C3B6E]/15 pt-3 text-xs text-gray-600", children: [ 2985 /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "h-4 w-4 shrink-0 text-[#3C3B6E]" }), 2986 "The Commissions AI Assistant uses this same evidence and labels official carrier schedules separately from historical paid rates, including effective dates, conditions, samples, periods, distributions, and confidence." 2987 ] }) 2988 ] }) }), 2989 /* @__PURE__ */ jsxRuntimeExports.jsx(PerformanceBonusTrackers, { isAdmin }), 2990 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-3 bg-white border border-gray-200 rounded-lg px-4 py-3", children: [ 2991 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-600 shrink-0", children: "Filter by period:" }), 2992 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2993 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "From" }),
2994 /* @__PURE__ */ jsxRuntimeExports.jsx( 2995 DatePicker, 2996 { 2997 value: dateFrom, 2998 onChange: (v) => setDateFrom(v ? v.slice(0, 7) : ""), 2999 placeholder: "Start month" 3000 } 3001 ) 3002 ] }), 3003 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 3004 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "To" }), 3005 /* @__PURE__ */ jsxRuntimeExports.jsx( 3006 DatePicker, 3007 { 3008 value: dateTo, 3009 onChange: (v) => setDateTo(v ? v.slice(0, 7) : ""), 3010 placeholder: "End month" 3011 } 3012 ) 3013 ] }), 3014 (dateFrom || dateTo) && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", className: "text-gray-400 hover:text-gray-600 h-8 px-2", onClick: () => { 3015 setDateFrom(""); 3016 setDateTo(""); 3017 }, children: "â Clear" }), 3018 (dateFrom || dateTo) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-[#3C3B6E] font-medium ml-auto", children: [ 3019 stmtData?.total ?? 0, 3020 " statement", 3021 (stmtData?.total ?? 0) !== 1 ? "s" : "", 3022 " found" 3023 ] }) 3024 ] }), 3025 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
3026 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm text-[#3C3B6E] flex items-center gap-2", children: [ 3027 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-4 h-4" }), 3028 " Commission Statements" 3029 ] }) }), 3030 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: statements.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12 text-gray-400", children: [ 3031 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-12 h-12 mx-auto mb-3 opacity-30" }), 3032 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium", children: "No statements uploaded yet." }), 3033 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: 'Click "Upload Statement" to register a carrier commission statement.' }) 3034 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-sm", children: [
3035 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-gray-200 text-xs text-gray-500 uppercase", children: [ 3036 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-left", children: "Period" }), 3037 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-left", children: "Carrier" }), 3038 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-left", children: "File" }), 3039 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-right", children: "Total Earned" }), 3040 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-center", children: "Status" }), 3041 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-left", children: "Notes" }), 3042 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "pb-2 text-right", children: "Actions" }) 3043 ] }) }), 3044 /* @__PURE__ */ jsxRuntimeExports.jsxs("tbody", { children: [ 3045 isAdmin && (() => { 3046 const shownPeriods = /* @__PURE__ */ new Set(); 3047 return statements.map((stmt) => { 3048 if (!periodsWithMultiple.has(stmt.period) || shownPeriods.has(stmt.period)) return null; 3049 shownPeriods.add(stmt.period); 3050 const group = periodGroups[stmt.period]; 3051 return /* @__PURE__ */ jsxRuntimeExports.jsx("tr", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("td", { colSpan: 7, className: "py-1.5 px-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between bg-amber-50 border border-amber-200 rounded-md px-3 py-2", children: [
3052 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-amber-800", children: [ 3053 /* @__PURE__ */ jsxRuntimeExports.jsx(Merge, { className: "w-3.5 h-3.5" }), 3054 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-medium", children: [ 3055 "Period ", 3056 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: stmt.period }), 3057 " has ", 3058 group.length, 3059 " separate statements â merge them to deliver combined commissions to each agent." 3060 ] }) 3061 ] }), 3062 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3063 Button, 3064 { 3065 size: "sm", 3066 className: "h-7 text-xs bg-amber-600 hover:bg-amber-700 text-white gap-1", 3067 onClick: () => { 3068 setMergePeriod(stmt.period); 3069 setMergePrimaryId(null); 3070 setMergeDialogOpen(true); 3071 }, 3072 children: [
3073 /* @__PURE__ */ jsxRuntimeExports.jsx(Merge, { className: "w-3 h-3" }), 3074 " Merge Period" 3075 ] 3076 } 3077 ) 3078 ] }) }) }, `merge-banner-${stmt.period}`); 3079 }); 3080 })(), 3081 statements.map((stmt) => { 3082 const cfg = STATUS_CONFIG[stmt.status] ?? STATUS_CONFIG.uploaded; 3083 const Icon = cfg.icon; 3084 return /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-gray-100 hover:bg-gray-50", children: [ 3085 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3 font-mono font-medium text-[#3C3B6E]", children: stmt.period }), 3086 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-xs border-[#3C3B6E] text-[#3C3B6E]", children: stmt.carrier }) }), 3087 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3 text-xs text-gray-600 max-w-[180px] truncate", children: stmt.fileName }),
3088 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3 text-right font-semibold text-green-700", children: isAdmin ? fmtCurrency(stmt.totalEarned) : fmtCurrency(stmt.agentGrandTotal ?? null) }), 3089 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: `inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium ${cfg.color}`, children: [ 3090 /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "w-3 h-3" }), 3091 cfg.label 3092 ] }) }), 3093 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3 text-xs text-gray-500 max-w-[120px] truncate", children: stmt.notes ?? "â" }), 3094 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "py-3 text-right", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-1", children: [ 3095 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs( 3096 Button, 3097 { 3098 variant: "ghost", 3099 size: "sm", 3100 className: "gap-1 text-emerald-700 hover:bg-emerald-50 hover:text-emerald-800 h-7 px-2 text-xs", 3101 title: `Add another carrier file to ${stmt.period}`, 3102 onClick: () => setAddFilePeriod(stmt.period), 3103 children: [
3104 /* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, { className: "w-3.5 h-3.5" }), 3105 " Add File" 3106 ] 3107 } 3108 ), 3109 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3110 Button, 3111 { 3112 variant: "ghost", 3113 size: "sm", 3114 onClick: () => setSelectedStatement({ id: stmt.id, period: stmt.period }), 3115 className: "gap-1 text-[#3C3B6E] hover:bg-[#3C3B6E]/10", 3116 children: [ 3117 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-3 h-3" }), 3118 " View ", 3119 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-3 h-3" }) 3120 ] 3121 } 3122 ), 3123 isAdmin && (confirmDeleteId === stmt.id ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [ 3124 /* @__P
3124URE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-red-600 font-medium", children: "Delete?" }), 3125 /* @__PURE__ */ jsxRuntimeExports.jsx( 3126 Button, 3127 { 3128 size: "sm", 3129 variant: "destructive", 3130 className: "h-7 px-2 text-xs", 3131 disabled: deleteStatement.isPending, 3132 onClick: () => deleteStatement.mutate({ statementId: stmt.id }), 3133 children: deleteStatement.isPending ? "..." : "Yes" 3134 } 3135 ), 3136 /* @__PURE__ */ jsxRuntimeExports.jsx( 3137 Button, 3138 { 3139 size: "sm", 3140 variant: "outline", 3141 className: "h-7 px-2 text-xs", 3142 onClick: () => setConfirmDeleteId(null), 3143 children: "No" 3144 } 3145 ) 3146 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx( 3147 Button, 3148 { 3149 size: "sm", 3150 variant: "ghost", 3151 className: "h-7 w-7 p-0 text-muted-foreground hover:text-red-600", 3152 onClick: () => setConfirmDeleteId(stmt.id), 3153 title: "Delete statement", 3154 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-3.5 h-3.5" }) 3155 } 3156 )) 3157 ] }) }) 3158 ] }, stmt.id); 3159 }) 3160 ] }) 3161 ] }) }) }) 3162 ] }), 3163 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: mergeDialogOpen, onOpenChange: (o) => { 3164 if (!o) { 3165 setMergeDialogOpen(false); 3166 setMergePeriod(null); 3167 setMergePrimaryId(null); 3168 } 3169 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-lg", children: [
3170 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 3171 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-[#3C3B6E] flex items-center gap-2", children: [ 3172 /* @__PURE__ */ jsxRuntimeExports.jsx(Merge, { className: "w-4 h-4" }), 3173 " Merge Statements â Period ", 3174 mergePeriod 3175 ] }), 3176 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "All transactions from the secondary statements will be moved into the primary statement and commission splits will be recalculated across the full combined set. The secondary statements will be permanently deleted." }) 3177 ] }), 3178 mergeGroup.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 3179 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3180 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs font-semibold text-gray-600 uppercase tracking-wide", children: "Primary Statement (kept)" }),
3181 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 space-y-1", children: mergeGroup.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: `flex items-center gap-3 p-2 rounded-md border cursor-pointer transition-colors ${s.id === effectivePrimaryId ? "border-[#3C3B6E] bg-[#3C3B6E]/5" : "border-gray-200 hover:border-gray-300"}`, children: [ 3182 /* @__PURE__ */ jsxRuntimeExports.jsx( 3183 "input", 3184 { 3185 type: "radio", 3186 name: "primary-stmt", 3187 checked: s.id === effectivePrimaryId, 3188 onChange: () => setMergePrimaryId(s.id), 3189 className: "accent-[#3C3B6E]" 3190 } 3191 ), 3192 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 3193 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-[#3C3B6E]", children: [ 3194 "#", 3195 s.id, 3196 " â ", 3197 s.fileName ?? "(no file)" 3198 ] }),
3199 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500", children: [ 3200 s.carrier ?? "Unknown carrier", 3201 " · ", 3202 fmtCurrency(s.totalEarned), 3203 " earned" 3204 ] }) 3205 ] }), 3206 s.id === effectivePrimaryId && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: "text-xs bg-[#3C3B6E] text-white", children: "Primary" }) 3207 ] }, s.id)) }) 3208 ] }), 3209 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 rounded-md p-3 text-xs text-gray-600 space-y-1", children: [ 3210 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-gray-700", children: "What will happen:" }), 3211 /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "list-disc list-inside space-y-0.5", children: [ 3212 /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [ 3213 "All transactions from ", 3214 secondaryIds.length, 3215 " secondary statement", 3216 secondaryIds.length !== 1 ? "s" : "", 3217 " will be moved to statement #", 3218 effectivePrimaryId 3219 ] }),
3220 /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: "Commission splits will be recalculated using the combined transaction set" }), 3221 /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [ 3222 "The ", 3223 secondaryIds.length, 3224 " secondary statement", 3225 secondaryIds.length !== 1 ? "s" : "", 3226 " will be permanently deleted" 3227 ] }), 3228 /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: "All file records will be reassigned to the primary statement" }) 3229 ] }) 3230 ] }) 3231 ] }), 3232 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { className: "gap-2", children: [ 3233 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => { 3234 setMergeDialogOpen(false); 3235 setMergePeriod(null); 3236 setMergePrimaryId(null); 3237 }, children: "Cancel" }), 3238 /* @__PURE__ */ jsxRuntimeExports.jsx( 3239 Button, 3240 { 3241 className: "bg-amber-600 hover:bg-amber-700 text-white gap-1", 3242 disabled: mergeStatements.isPending || secondaryIds.length === 0, 3243 onClick: () => { 3244 if (effectivePrimaryId && secondaryIds.length > 0) { 3245 mergeStatements.mutate({ primaryId: effectivePrimaryId, secondaryIds }); 3246 } 3247 },
3248 children: mergeStatements.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 3249 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3.5 h-3.5 animate-spin" }), 3250 " Merging..." 3251 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 3252 /* @__PURE__ */ jsxRuntimeExports.jsx(Merge, { className: "w-3.5 h-3.5" }), 3253 " Merge ", 3254 mergeGroup.length, 3255 " Statements" 3256 ] }) 3257 } 3258 ) 3259 ] }) 3260 ] }) }), 3261 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: !!mergeReport, onOpenChange: (o) => { 3262 if (!o) setMergeReport(null); 3263 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-3xl max-h-[90vh] overflow-y-auto", children: [ 3264 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 3265 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-[#3C3B6E] flex items-center gap-2", children: [
3266 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "w-5 h-5 text-green-600" }), 3267 "Merge Complete â Period ", 3268 mergeReport?.period, 3269 " Summary Report" 3270 ] }), 3271 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogDescription, { children: [ 3272 "Generated ", 3273 mergeReport ? new Date(mergeReport.mergedAt).toLocaleString() : "", 3274 " · Statement #", 3275 mergeReport?.primaryStatementId 3276 ] }) 3277 ] }), 3278 mergeReport && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-5 text-sm", children: [ 3279 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3280 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-[#3C3B6E] text-xs uppercase tracking-wide mb-2", children: "Source Statements Merged" }), 3281 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-gray-200 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [
3282 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-[#3C3B6E]/5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 3283 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-3 py-2 font-semibold text-[#3C3B6E]", children: "#" }), 3284 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-3 py-2 font-semibold text-[#3C3B6E]", children: "File" }), 3285 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-3 py-2 font-semibold text-[#3C3B6E]", children: "Carrier" }), 3286 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Total Earned" }), 3287 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-center px-3 py-2 font-semibold text-[#3C3B6E]", children: "Role" }) 3288 ] }) }), 3289 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: mergeReport.sourceStatements.map((s) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-gray-100", children: [
3290 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 font-mono text-gray-500", children: s.id }), 3291 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 max-w-[200px] truncate text-gray-700", children: s.fileName }), 3292 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-gray-600", children: s.carrier || "â" }), 3293 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right font-semibold text-green-700", children: fmtCurrency(s.totalEarned) }), 3294 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${s.role === "primary" ? "bg-[#3C3B6E] text-white" : "bg-amber-100 text-amber-800"}`, children: s.role === "primary" ? "Primary" : "Merged In" }) }) 3295 ] }, s.id)) }) 3296 ] }) }) 3297 ] }), 3298 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
3299 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-[#3C3B6E] text-xs uppercase tracking-wide mb-2", children: "Combined Totals" }), 3300 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4", children: [ 3301 { label: "Total Transactions", value: mergeReport.totalTransactions.toString(), color: "text-[#3C3B6E]" }, 3302 { label: "Total Agency Earned", value: fmtCurrency(mergeReport.totalEarned), color: "text-green-700" }, 3303 { label: "SIAA Earned", value: `${fmtCurrency(mergeReport.siaaEarned)} (${mergeReport.siaaTxnCount} txns)`, color: "text-blue-700" }, 3304 { label: "Non-SIAA Earned", value: `${fmtCurrency(mergeReport.nonSiaaEarned)} (${mergeReport.nonSiaaTxnCount} txns)`, color: "text-purple-700" } 3305 ].map((k) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 rounded-md p-3 border border-gray-100", children: [ 3306 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: k.label }),
3307 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `font-bold text-sm mt-0.5 ${k.color}`, children: k.value }) 3308 ] }, k.label)) }) 3309 ] }), 3310 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3311 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-[#3C3B6E] text-xs uppercase tracking-wide mb-2", children: "Carrier Breakdown" }), 3312 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-gray-200 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [ 3313 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-[#3C3B6E]/5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 3314 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-3 py-2 font-semibold text-[#3C3B6E]", children: "Carrier" }), 3315 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-center px-3 py-2 font-semibold text-[#3C3B6E]", children: "Type" }),
3316 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Transactions" }), 3317 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Earned" }) 3318 ] }) }), 3319 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: mergeReport.carrierBreakdown.map((c) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-gray-100 hover:bg-gray-50", children: [ 3320 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 font-medium text-gray-800", children: c.carrier }), 3321 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${c.isNonSiaa ? "bg-purple-100 text-purple-700" : "bg-blue-100 text-blue-700"}`, children: c.isNonSiaa ? "Non-SIAA" : "SIAA" }) }), 3322 /* @__P
3322URE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right text-gray-600", children: c.txnCount }), 3323 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right font-semibold text-green-700", children: fmtCurrency(c.earned) }) 3324 ] }, c.carrier)) }) 3325 ] }) }) 3326 ] }), 3327 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3328 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-[#3C3B6E] text-xs uppercase tracking-wide mb-2", children: "Recalculated Agent Commission Splits" }), 3329 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-gray-200 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [ 3330 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-[#3C3B6E]/5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 3331 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-3 py-2 font-semibold text-[#3C3B6E]", children: "Agent" }),
3332 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Transactions" }), 3333 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Agency Earned" }), 3334 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Eff. Split %" }), 3335 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right px-3 py-2 font-semibold text-[#3C3B6E]", children: "Agent Due" }) 3336 ] }) }), 3337 /* @__PURE__ */ jsxRuntimeExports.jsxs("tbody", { children: [ 3338 mergeReport.agentSplits.map((a) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-gray-100 hover:bg-gray-50", children: [ 3339 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 font-medium text-[#3C3B6E]", children: a.agentName }), 3340 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right text-gray-600", children: a.transactionCount }),
3341 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right text-gray-700", children: fmtCurrency(a.totalEarned) }), 3342 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[#3C3B6E]", children: fmtPct(a.splitPct) }) }), 3343 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right font-bold text-[#B22234]", children: fmtCurrency(a.grandTotal) }) 3344 ] }, a.agentId)), 3345 /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t-2 border-[#3C3B6E]/20 bg-[#3C3B6E]/5 font-semibold", children: [ 3346 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-[#3C3B6E]", children: "Total" }), 3347 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right text-[#3C3B6E]", children: mergeReport.totalTransactions }), 3348 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right text-[#3C3B6E]", children: fmtCurrency(mergeReport.totalEarned) }),
3349 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2" }), 3350 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 text-right text-[#B22234]", children: fmtCurrency(mergeReport.agentSplits.reduce((s, a) => s + parseFloat(a.grandTotal), 0).toFixed(2)) }) 3351 ] }) 3352 ] }) 3353 ] }) }) 3354 ] }) 3355 ] }), 3356 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { className: "gap-2 pt-2", children: [ 3357 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3358 Button, 3359 { 3360 variant: "outline", 3361 className: "gap-1.5 text-[#3C3B6E] border-[#3C3B6E]/30", 3362 onClick: () => { 3363 if (!mergeReport) return; 3364 const rows = mergeReport.agentSplits.map( 3365 (a) => `<tr><td>${a.agentName}</td><td style="text-align:right">${a.transactionCount}</td><td style="text-align:right">${parseFloat(a.totalEarned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</td><td style="text-align:right">${(parseFloat(a.splitPct) * 100).toFixed(0)}%</td><td style="text-align:right">${parseFloat(a.grandTotal).toLocaleString("en-US", { style: "currency", currency: "USD" })}</td></tr>` 3366 ).join(""); 3367 const carriers = mergeReport.carrierBreakdown.map( 3368 (c) => `<tr><td>${c.carrier}</td><td>${c.isNonSiaa ? "Non-SIAA" : "SIAA"}</td><td style="text-align:right">${c.txnCount}</td><td style="text-align:right">${parseFloat(c.earned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</td></tr>` 3369 ).join(""); 3370 const sources = mergeReport.sourceStatements.map( 3371 (s) => `<tr><td>#${s.id}</td><td>${s.fileName}</td><td>${s.carrier || "â"}</td><td style="text-align:right">${parseFloat(s.totalEarned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</td><td>${s.role === "primary" ? "Primary" : "Merged In"}</td></tr>` 3372 ).join(""); 3373 const totalDue = mergeReport.agentSplits.reduce((s, a) => s + parseFloat(a.grandTotal), 0); 3374 const html = `<!DOCTYPE html><html><head><title>Merge Report â ${mergeReport.period}</title><style> 3375 body{font-family:Arial,sans-serif;font-size:11px;color:#111;margin:24px} 3376 h1{font-size:16px;color:#3C3B6E;margin-bottom:4px} 3377 h2{font-size:12px;color:#3C3B6E;margin:16px 0 6px;border-bottom:1px solid #ccc;padding-bottom:3px} 3378 table{width:100%;border-collapse:collapse;margin-bottom:8px} 3379 th{background:#3C3B6E;color:#fff;padding:5px 8px;text-align:left;font-size:10px} 3380 td{padding:4px 8px;border-bottom:1px solid #eee} 3381 .kpi{display:inline-block;margin:4px 8px 4px 0;padding:6px 12px;background:#f5f5f5;border-radius:4px} 3382 .kpi-label{font-size:9px;color:#666} 3383 .kpi-value{font-size:13px;font-weight:bold;color:#3C3B6E} 3384 .total-row td{font-weight:bold;background:#f0f4f8;border-top:2px solid #3C3B6E} 3385 .footer{margin-top:24px;font-size:9px;color:#999;border-top:1px solid #eee;padding-top:8px} 3386 </style></head><body> 3387 <h1>Commission Merge Report â Period ${mergeReport.period}</h1> 3388 <p style="color:#666;font-size:10px">Statement #${mergeReport.primaryStatementId} · Generated ${new Date(mergeReport.mergedAt).toLocaleString()} · Expert Protection Services</p> 3389 <div> 3390 <span class="kpi"><div class="kpi-label">Total Transactions</div><div class="kpi-value">${mergeReport.totalTransactions}</div></span> 3391 <span class="kpi"><div class="kpi-label">Total Agency Earned</div><div class="kpi-value">${parseFloat(mergeReport.totalEarned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</div></span> 3392 <span class="kpi"><div class="kpi-label">SIAA Earned</div><div class="kpi-value">${parseFloat(mergeReport.siaaEarned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</div></span>
3393 <span class="kpi"><div class="kpi-label">Non-SIAA Earned</div><div class="kpi-value">${parseFloat(mergeReport.nonSiaaEarned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</div></span> 3394 </div> 3395 <h2>Source Statements</h2> 3396 <table><thead><tr><th>#</th><th>File</th><th>Carrier</th><th>Total Earned</th><th>Role</th></tr></thead><tbody>${sources}</tbody></table> 3397 <h2>Carrier Breakdown</h2> 3398 <table><thead><tr><th>Carrier</th><th>Type</th><th>Transactions</th><th>Earned</th></tr></thead><tbody>${carriers}</tbody></table> 3399 <h2>Agent Commission Splits</h2> 3400 <table><thead><tr><th>Agent</th><th>Transactions</th><th>Agency Earned</th><th>Split %</th><th>Agent Due</th></tr></thead><tbody>${rows}<tr class="total-row"><td>TOTAL</td><td style="text-align:right">${mergeReport.totalTransactions}</td><td style="text-align:right">${parseFloat(mergeReport.totalEarned).toLocaleString("en-US", { style: "currency", currency: "USD" })}</td><td></td><td style="text-align:right">${totalDue.toLocaleString("en-US", { style: "currency", currency: "USD" })}</td></tr></tbody></table> 3401 <div class="footer">Expert Protection Services · Confidential · For internal use only</div> 3402 </body></html>`; 3403 const w = window.open("", "_blank"); 3404 if (w) { 3405 w.document.write(html); 3406 w.document.close(); 3407 w.print(); 3408 } 3409 }, 3410 children: [
3411 /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "w-3.5 h-3.5" }), 3412 " Download PDF" 3413 ] 3414 } 3415 ), 3416 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { className: "bg-[#3C3B6E] hover:bg-[#3C3B6E] text-white", onClick: () => setMergeReport(null), children: "Close" }) 3417 ] }) 3418 ] }) }), 3419 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(AgentYTDSummary, {}), 3420 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-[#3C3B6E]/5 border border-[#3C3B6E]/20 rounded-lg p-4 text-xs text-[#3C3B6E]", children: [ 3421 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 3422 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-4 h-4 shrink-0 mt-0.5 text-[#B22234]" }), 3423 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3424 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Commission Information â Confidential." }), 3425 " Commission data is for internal use only and must never appear in any client-facing communication. Final payment instructions require owner (Greg Fay) approval before release." 3426 ] }) 3427 ] }),
3428 /* @__PURE__ */ jsxRuntimeExports.jsx( 3429 AgentChat, 3430 { 3431 title: "Commissions AI Assistant", 3432 greeting: "Hello! I can help you understand commission statements, calculate earnings, explain SIAA vs non-SIAA splits, and answer questions about your compensation structure. What would you like to know?", 3433 quickPrompts: [ 3434 "How do SIAA vs non-SIAA commissions differ?", 3435 "Explain how agent splits are calculated", 3436 "What is profit sharing and how is it earned?", 3437 "How do I read my commission statement?" 3438 ], 3439 onSend: async (message, history) => { 3440 const result = await chatMutation.mutateAsync({ message, history }); 3441 return String(result.result ?? ""); 3442 }, 3443 isPending: chatMutation.isPending 3444 } 3445 ) 3446 ] }) 3447 ] }); 3448} 3449 3450export { CommissionsPanel 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.