1(globalThis["TURBOPACK"] || (globalThis["TURBOPACK"] = [])).push([typeof document === "object" ? document.currentScript : undefined, 2425961, ((__turbopack_context__) => { 3"use strict"; 4 5// MERGED MODULE: [project]/node_modules/@open-mercato/core/dist/modules/customers/components/detail/ActivitiesSection.js [app-client] (ecmascript) 6; 7var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 8var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 9var __TURBOPACK__imported__module__503116__ = __turbopack_context__.i(503116); 10var __TURBOPACK__imported__module__555436__ = __turbopack_context__.i(555436); 11var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 12var __TURBOPACK__imported__module__490746__ = __turbopack_context__.i(490746); 13var __TURBOPACK__imported__module__484973__ = __turbopack_context__.i(484973); 14var __TURBOPACK__imported__module__110035__ = __turbopack_context__.i(110035); 15var __TURBOPACK__imported__module__443530__ = __turbopack_context__.i(443530); 16// MERGED MODULE: [project]/node_modules/@open-mercato/core/dist/modules/customers/components/detail/ActivityTimelineFilters.js [app-client] (ecmascript) 17; 18var __TURBOPACK__imported__module__843476__1 = __TURBOPACK__imported__module__843476__; 19var __TURBOPACK__imported__module__271645__1 = __TURBOPACK__imported__module__271645__; 20var __TURBOPACK__imported__module__343432__ = __turbopack_context__.i(343432); 21var __TURBOPACK__imported__module__263488__ = __turbopack_context__.i(263488); 22var __TURBOPACK__imported__module__761911__ = __turbopack_context__.i(761911); 23var __TURBOPACK__imported__module__999353__ = __turbopack_context__.i(999353); 24var __TURBOPACK__imported__module__939951__ = __turbopack_context__.i(939951); 25var __TURBOPACK__imported__module__649582__ = __turbopack_context__.i(649582); 26var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 27var __TURBOPACK__imported__module__928441__1 = __TURBOPACK__imported__module__928441__; 28var __TURBOPACK__imported__module__110035__1 = __TURBOPACK__imported__module__110035__; 29var __TURBOPACK__imported__module__741870__ = __turbopack_context__.i(741870); 30var __TURBOPACK__imported__module__388528__ = __turbopack_context__.i(388528); 31var __TURBOPACK__imported__module__490746__1 = __TURBOPACK__imported__module__490746__; 32"use client"; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42const FILTER_TYPES = [ 43 { 44 type: "note", 45 icon: __TURBOPACK__imported__module__999353__["StickyNote"] 46 }, 47 { 48 type: "call", 49 icon: __TURBOPACK__imported__module__343432__["Phone"] 50 }, 51 { 52 type: "meeting", 53 icon: __TURBOPACK__imported__module__761911__["Users"] 54 }, 55 { 56 type: "email", 57 icon: __TURBOPACK__imported__module__263488__["Mail"] 58 }, 59 { 60 type: "task", 61 icon: __TURBOPACK__imported__module__939951__["ListTodo"] 62 } 63]; 64const CHIP_BASE = "inline-flex h-7 items-center gap-1.5 rounded-lg px-2.5 text-sm font-medium transition-colors"; 65const CHIP_INACTIVE = "border border-border bg-card text-muted-foreground hover:bg-accent/40"; 66const CHIP_ACTIVE = "border border-status-info-border bg-status-info-bg text-status-info-text"; 67function ActivityTimelineFilters({ entityId, activeTypes, dateFrom, dateTo, onTypesChange, onDateFromChange, onDateToChange, onReset }) { 68 const t = (0, __TURBOPACK__imported__module__928441__1["useT"])(); 69 const hasActiveFilters = activeTypes.length > 0 || dateFrom || dateTo; 70 const allActive = activeTypes.length === 0; 71 const [counts, setCounts] = __TURBOPACK__imported__module__271645__1["useState"](null); 72 __TURBOPACK__imported__module__271645__1["useEffect"](()=>{ 73 if (!entityId) return; 74 const controller = new AbortController(); 75 void (async ()=>{ 76 try { 77 const payload = await (0, __TURBOPACK__imported__module__490746__1["readApiResultOrThrow"])(`/api/customers/interactions/counts?entityId=${encodeURIComponent(entityId)}`, { 78 signal: controller.signal 79 }); 80 const source = payload.result ?? payload; 81 setCounts({ 82 call: source.call ?? 0, 83 email: source.email ?? 0, 84 meeting: source.meeting ?? 0, 85 note: source.note ?? 0, 86 task: source.task ?? 0, 87 total: source.total ?? 0 88 }); 89 } catch { 90 setCounts(null); 91 } 92 })(); 93 return ()=>controller.abort(); 94 }, [ 95 entityId 96 ]); 97 const handleTypeToggle = __TURBOPACK__imported__module__271645__1["useCallback"]((type)=>{ 98 if (activeTypes.includes(type)) { 99 onTypesChange(activeTypes.filter((filterType)=>filterType !== type)); 100 } else { 101 onTypesChange([ 102 ...activeTypes, 103 type 104 ]); 105 } 106 }, [ 107 activeTypes, 108 onTypesChange 109 ]); 110 const handleSelectAll = __TURBOPACK__imported__module__271645__1["useCallback"](()=>{ 111 onTypesChange([]); 112 }, [ 113 onTypesChange 114 ]); 115 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("div", { 116 className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", 117 children: [
118 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("div", { 119 className: "flex flex-wrap items-center gap-2.5", 120 children: [ 121 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__110035__1["Button"], { 122 type: "button", 123 variant: "ghost", 124 size: "sm", 125 onClick: handleSelectAll, 126 "aria-pressed": allActive, 127 className: (0, __TURBOPACK__imported__module__406911__["cn"])(CHIP_BASE, allActive ? CHIP_ACTIVE : CHIP_INACTIVE), 128 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("span", { 129 children: t("customers.timeline.filter.all", "All Activities") 130 }) 131 }), 132 FILTER_TYPES.map(({ type, icon: Icon })=>{ 133 const isActive = activeTypes.includes(type); 134 const count = counts?.[type]; 135 const hasCount = typeof count === "number" && count > 0; 136 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])(__TURBOPACK__imported__module__110035__1["Button"], { 137 type: "button", 138 variant: "ghost", 139 size: "sm", 140 onClick: ()=>handleTypeToggle(type), 141 "aria-pressed": isActive, 142 className: (0, __TURBOPACK__imported__module__406911__["cn"])(CHIP_BASE, isActive ? CHIP_ACTIVE : CHIP_INACTIVE), 143 children: [
144 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(Icon, { 145 className: "size-[18px] shrink-0" 146 }), 147 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("span", { 148 children: [ 149 t(`customers.timeline.filter.${type}`, type), 150 hasCount ? ` ${count}` : "" 151 ] 152 }) 153 ] 154 }, type); 155 }) 156 ] 157 }), 158 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])(__TURBOPACK__imported__module__388528__["Popover"], { 159 children: [ 160 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__388528__["PopoverTrigger"], { 161 asChild: true, 162 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 163 type: "button", 164 variant: "outline", 165 size: "sm", 166 className: "size-7 rounded-md text-muted-foreground", 167 "aria-label": t("customers.people.detail.activities.moreFilters", "More filters"), 168 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__649582__["SlidersHorizontal"], { 169 className: "size-3.5" 170 }) 171 }) 172 }),
173 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])(__TURBOPACK__imported__module__388528__["PopoverContent"], { 174 align: "end", 175 className: "w-72 space-y-3", 176 children: [ 177 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("div", { 178 className: "space-y-1.5", 179 children: [ 180 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("label", { 181 className: "text-xs font-medium", 182 children: t("customers.activities.filters.dateRange", "Date range") 183 }), 184 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("div", { 185 className: "flex items-center gap-2", 186 children: [
187 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("input", { 188 type: "date", 189 value: dateFrom, 190 onChange: (event)=>onDateFromChange(event.target.value), 191 className: "h-8 w-full rounded-md border bg-background px-2 text-xs focus:outline-none focus:ring-1 focus:ring-ring", 192 "aria-label": t("customers.timeline.filter.from", "From date") 193 }), 194 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("span", { 195 className: "shrink-0 text-xs text-muted-foreground", 196 children: "\u2014" 197 }), 198 /* @__P
198URE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("input", { 199 type: "date", 200 value: dateTo, 201 onChange: (event)=>onDateToChange(event.target.value), 202 className: "h-8 w-full rounded-md border bg-background px-2 text-xs focus:outline-none focus:ring-1 focus:ring-ring", 203 "aria-label": t("customers.timeline.filter.to", "To date") 204 }) 205 ] 206 }) 207 ] 208 }), 209 hasActiveFilters ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__110035__1["Button"], { 210 type: "button", 211 variant: "ghost", 212 size: "sm", 213 onClick: onReset, 214 className: "h-7 w-full text-xs", 215 children: t("customers.activities.filters.clearAll", "Clear filters") 216 }) : null 217 ] 218 }) 219 ] 220 }) 221 ] 222 }); 223} 224; 225// MERGED MODULE: [project]/node_modules/@open-mercato/core/dist/modules/customers/components/detail/ActivityTimeline.js [app-client] (ecmascript) 226; 227var __TURBOPACK__imported__module__843476__2 = __TURBOPACK__imported__module__843476__; 228var __TURBOPACK__imported__module__271645__2 = __TURBOPACK__imported__module__271645__; 229var __TURBOPACK__imported__module__643531__ = __turbopack_context__.i(643531); 230var __TURBOPACK__imported__module__939951__1 = __TURBOPACK__imported__module__939951__; 231var __TURBOPACK__imported__module__343432__1 = __TURBOPACK__imported__module__343432__; 232var __TURBOPACK__imported__module__263488__1 = __TURBOPACK__imported__module__263488__; 233var __TURBOPACK__imported__module__761911__1 = __TURBOPACK__imported__module__761911__; 234var __TURBOPACK__imported__module__999353__1 = __TURBOPACK__imported__module__999353__; 235var __TURBOPACK__imported__module__284614__ = __turbopack_context__.i(284614); 236var __TURBOPACK__imported__module__928441__2 = __TURBOPACK__imported__module__928441__; 237var __TURBOPACK__imported__module__110035__2 = __TURBOPACK__imported__module__110035__; 238// MERGED MODULE: [project]/node_modules/@open-mercato/core/dist/modules/customers/components/detail/AiActionChips.js [app-client] (ecmascript) 239; 240var __TURBOPACK__imported__module__843476__3 = __TURBOPACK__imported__module__843476__; 241var __TURBOPACK__imported__module__928441__3 = __TURBOPACK__imported__module__928441__; 242var __TURBOPACK__imported__module__653935__ = __turbopack_context__.i(653935); 243var __TURBOPACK__imported__module__110035__3 = __TURBOPACK__imported__module__110035__; 244var __TURBOPACK__imported__module__220339__ = __turbopack_context__.i(220339); 245var __TURBOPACK__imported__module__931483__ = __turbopack_context__.i(931483); 246"use client"; 247; 248; 249; 250; 251; 252; 253function AiActionChips({ activityType }) { 254 const t = (0, __TURBOPACK__imported__module__928441__3["useT"])(); 255 const actions = (0, __TURBOPACK__imported__module__931483__["resolveAiActions"])(activityType, __TURBOPACK__imported__module__931483__["AI_TIMELINE_ACTIONS_BY_TYPE"]); 256 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])(__TURBOPACK__imported__module__220339__["TooltipProvider"], { 257 delayDuration: 300, 258 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])("div", { 259 className: "flex items-center gap-1.5", 260 children: [
261 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])("span", { 262 className: "text-[9px] font-bold text-muted-foreground/70", 263 children: t("customers.ai.prefix", "AI:") 264 }), 265 actions.map((action)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])(__TURBOPACK__imported__module__220339__["Tooltip"], { 266 children: [ 267 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])(__TURBOPACK__imported__module__220339__["TooltipTrigger"], { 268 asChild: true, 269 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])(__TURBOPACK__imported__module__110035__3["Button"], { 270 type: "button", 271 variant: "outline", 272 size: "sm", 273 className: "h-auto gap-1 rounded-[4px] border-dashed bg-card pl-1.5 pr-[7px] py-[3px] text-[9px] font-medium text-muted-foreground/70 shadow-none hover:border-muted-foreground hover:text-foreground", 274 children: [
275 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])(__TURBOPACK__imported__module__653935__["AiIcon"], { 276 className: "size-2.5 shrink-0" 277 }), 278 t(action.i18nKey, action.fallback) 279 ] 280 }) 281 }), 282 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])(__TURBOPACK__imported__module__220339__["TooltipContent"], { 283 side: "bottom", 284 className: "text-xs", 285 children: t("customers.ai.comingSoon", "Coming soon") 286 }) 287 ] 288 }, action.key)) 289 ] 290 }) 291 }); 292} 293; 294var __TURBOPACK__imported__module__511990__ = __turbopack_context__.i(511990); 295"use client"; 296; 297; 298; 299; 300; 301; 302; 303const TYPE_ICONS = { 304 call: __TURBOPACK__imported__module__343432__1["Phone"], 305 email: __TURBOPACK__imported__module__263488__1["Mail"], 306 meeting: __TURBOPACK__imported__module__761911__1["Users"], 307 note: __TURBOPACK__imported__module__999353__1["StickyNote"], 308 task: __TURBOPACK__imported__module__939951__1["ListTodo"] 309}; 310function ActivityTimeline({ activities, onEdit, onMarkDone }) { 311 const t = (0, __TURBOPACK__imported__module__928441__2["useT"])(); 312 if (activities.length === 0) { 313 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 314 className: "py-6 text-center text-sm text-muted-foreground", 315 children: t("customers.timeline.empty", "No activities match the current filters.") 316 }); 317 } 318 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 319 children: activities.map((activity, index)=>{ 320 const dateStr = activity.scheduledAt ?? activity.occurredAt ?? activity.createdAt; 321 const activityYear = dateStr ? new Date(dateStr).getFullYear() : null; 322 const prevDateStr = index > 0 ? activities[index - 1].scheduledAt ?? activities[index - 1].occurredAt ?? activities[index - 1].createdAt : null; 323 const prevYear = prevDateStr ? new Date(prevDateStr).getFullYear() : null; 324 const showYearSeparator = activityYear !== null && prevYear !== null && activityYear !== prevYear; 325 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__271645__2["Fragment"], { 326 children: [ 327 showYearSeparator && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 328 className: "flex items-center gap-3 py-3 px-5", 329 children: [
330 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 331 className: "h-px flex-1 bg-border" 332 }), 333 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 334 className: "text-xs font-semibold text-muted-foreground", 335 children: t("customers.activities.yearSeparator", "{year}", { 336 year: activityYear 337 }) 338 }), 339 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 340 className: "h-px flex-1 bg-border" 341 }) 342 ] 343 }), 344 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(TimelineEntry, { 345 activity, 346 t, 347 withBorder: index < activities.length - 1, 348 onEdit, 349 onMarkDone 350 }) 351 ] 352 }, activity.id); 353 }) 354 }); 355} 356function TimelineEntry({ activity, t, withBorder, onEdit, onMarkDone }) { 357 const dateStr = activity.scheduledAt ?? activity.occurredAt ?? activity.createdAt; 358 const TypeIcon = TYPE_ICONS[activity.interactionType]; 359 const title = activity.title ?? activity.body ?? activity.interactionType; 360 const duration = activity.duration ? ` (${activity.duration} min)` : ""; 361 const isOpen = (0, __TURBOPACK__imported__module__511990__["isOpenInteractionStatus"])(activity.status); 362 const [markingDone, setMarkingDone] = __TURBOPACK__imported__module__271645__2["useState"](false); 363 const handleMarkDone = __TURBOPACK__imported__module__271645__2["useCallback"](async (event)=>{ 364 event.stopPropagation(); 365 if (!onMarkDone || markingDone) return; 366 setMarkingDone(true); 367 try { 368 await onMarkDone(activity.id, activity.updatedAt); 369 } finally{ 370 setMarkingDone(false); 371 } 372 }, [ 373 activity.id, 374 markingDone, 375 onMarkDone 376 ]); 377 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 378 className: `py-2.5 ${withBorder ? "border-b border-border/60" : ""} ${onEdit ? "cursor-pointer hover:bg-accent/40 transition-colors" : ""}`, 379 onClick: ()=>onEdit?.(activity), 380 role: onEdit ? "button" : void 0, 381 tabIndex: onEdit ? 0 : void 0, 382 onKeyDown: onEdit ? (e)=>{ 383 if (e.key === "Enter") onEdit(activity); 384 } : void 0, 385 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 386 className: "grid items-start gap-3", 387 style: { 388 gridTemplateColumns: "75px 32px 1fr" 389 }, 390 children: [
391 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 392 className: "shrink-0", 393 children: [ 394 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 395 className: "block text-[11px] font-semibold leading-tight text-foreground", 396 children: formatRelativeDate(dateStr, t) 397 }), 398 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 399 className: "block text-[10px] leading-tight text-muted-foreground", 400 children: formatTime(dateStr) 401 }) 402 ] 403 }), 404 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 405 className: "flex size-8 items-center justify-center rounded-md bg-muted shrink-0", 406 children: TypeIcon ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(TypeIcon, { 407 className: "size-3.5 text-muted-foreground" 408 }) : null 409 }),
410 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 411 className: "min-w-0 space-y-1.5", 412 children: [ 413 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 414 className: "flex items-start justify-between gap-2", 415 children: [ 416 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("span", { 417 className: "block text-[12px] font-semibold leading-tight text-foreground", 418 children: [ 419 title, 420 duration 421 ] 422 }), 423 isOpen && onMarkDone ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 424 type: "button", 425 variant: "default", 426 size: "sm", 427 disabled: markingDone, 428 onClick: handleMarkDone, 429 className: "h-7 shrink-0 text-xs", 430 children: [
431 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__643531__["Check"], { 432 className: "size-3.5" 433 }), 434 t("customers.activities.actions.markDone", "Mark done") 435 ] 436 }) : null 437 ] 438 }), 439 activity.body && activity.title && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("p", { 440 className: "text-[11px] leading-snug text-muted-foreground", 441 children: activity.body 442 }), 443 activity.authorName && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 444 className: "flex items-center gap-1 text-[10px] text-muted-foreground", 445 children: [
446 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__284614__["User"], { 447 className: "size-2.5 shrink-0" 448 }), 449 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 450 children: t("customers.timeline.author", "by {{name}}", { 451 name: activity.authorName 452 }) 453 }) 454 ] 455 }), 456 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(AiActionChips, { 457 activityType: activity.interactionType 458 }) 459 ] 460 }) 461 ] 462 }) 463 }); 464} 465function formatRelativeDate(isoString, t) { 466 try { 467 const date = new Date(isoString); 468 const now = /* @__PURE__ */ new Date(); 469 const dateDay = new Date(date.getFullYear(), date.getMonth(), date.getDate()); 470 const nowDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()); 471 const diffDays = Math.round((nowDay.getTime() - dateDay.getTime()) / (1e3 * 60 * 60 * 24)); 472 if (diffDays === 0) return t("customers.timeline.date.today", "today"); 473 if (diffDays === 1) return t("customers.timeline.date.yesterday", "yesterday"); 474 return date.toLocaleDateString(void 0, { 475 day: "numeric", 476 month: "short" 477 }); 478 } catch { 479 return ""; 480 } 481} 482function formatTime(isoString) { 483 try { 484 return new Date(isoString).toLocaleTimeString(void 0, { 485 hour: "2-digit", 486 minute: "2-digit" 487 }); 488 } catch { 489 return ""; 490 } 491} 492; 493var __TURBOPACK__imported__module__488166__ = __turbopack_context__.i(488166); 494"use client"; 495; 496; 497; 498; 499; 500; 501; 502; 503; 504; 505; 506const logger = (0, __TURBOPACK__imported__module__488166__["createLogger"])("customers"); 507function toDateOnly(value) { 508 if (!value) return ""; 509 const date = new Date(value); 510 return Number.isNaN(date.getTime()) ? "" : date.toISOString().slice(0, 10); 511} 512function normalizeLegacyActivity(activity) { 513 return { 514 id: activity.id, 515 interactionType: activity.activityType, 516 title: activity.subject ?? null, 517 body: activity.body ?? null, 518 status: "done", 519 scheduledAt: null, 520 occurredAt: activity.occurredAt ?? null, 521 priority: null, 522 authorUserId: activity.authorUserId ?? null, 523 ownerUserId: null, 524 appearanceIcon: activity.appearanceIcon ?? null, 525 appearanceColor: activity.appearanceColor ?? null, 526 source: "legacy-activity", 527 entityId: activity.entityId ?? null, 528 dealId: activity.dealId ?? null, 529 organizationId: null, 530 tenantId: null, 531 authorName: activity.authorName ?? null, 532 authorEmail: activity.authorEmail ?? null, 533 dealTitle: activity.dealTitle ?? null, 534 customValues: activity.customValues ?? null, 535 createdAt: activity.createdAt, 536 updatedAt: activity.createdAt 537 }; 538} 539function sortTimelineActivities(items) { 540 const now = Date.now(); 541 return [ 542 ...items 543 ].sort((left, right)=>{ 544 const leftScheduled = left.scheduledAt ? new Date(left.scheduledAt).getTime() : Number.NaN; 545 const rightScheduled = right.scheduledAt ? new Date(right.scheduledAt).getTime() : Number.NaN; 546 const leftIsPlanned = left.status === "planned" && Number.isFinite(leftScheduled); 547 const rightIsPlanned = right.status === "planned" && Number.isFinite(rightScheduled); 548 const leftIsUpcoming = leftIsPlanned && leftScheduled >= now; 549 const rightIsUpcoming = rightIsPlanned && rightScheduled >= now; 550 if (leftIsUpcoming !== rightIsUpcoming) { 551 return leftIsUpcoming ? -1 : 1; 552 } 553 if (leftIsUpcoming && rightIsUpcoming) { 554 if (leftScheduled === rightScheduled) return left.id.localeCompare(right.id); 555 return leftScheduled - rightScheduled; 556 } 557 const leftTime = left.occurredAt ?? left.createdAt; 558 const rightTime = right.occurredAt ?? right.createdAt; 559 const compare = rightTime.localeCompare(leftTime); 560 if (compare !== 0) return compare; 561 return right.id.localeCompare(left.id); 562 }); 563}
564function ActivitiesSection({ entityId, entityName, dealId, useCanonicalInteractions = false, onActionChange, onLoadingChange, refreshKey = 0, onEditActivity, runGuardedMutation, excludeInteractionType = "task" }) { 565 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 566 const [filterTypes, setFilterTypes] = __TURBOPACK__imported__module__271645__["useState"]([]); 567 const [filterDateFrom, setFilterDateFrom] = __TURBOPACK__imported__module__271645__["useState"](""); 568 const [filterDateTo, setFilterDateTo] = __TURBOPACK__imported__module__271645__["useState"](""); 569 const [searchTerm, setSearchTerm] = __TURBOPACK__imported__module__271645__["useState"](""); 570 const [activities, setActivities] = __TURBOPACK__imported__module__271645__["useState"]([]); 571 const [loading, setLoading] = __TURBOPACK__imported__module__271645__["useState"](false); 572 const [hasMore, setHasMore] = __TURBOPACK__imported__module__271645__["useState"](false); 573 const [loadedPages, setLoadedPages] = __TURBOPACK__imported__module__271645__["useState"](1); 574 const searchInputRef = __TURBOPACK__imported__module__271645__["useRef"](null); 575 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 576 if (!entityId) return; 577 function handleShortcut(event) { 578 if ((event.metaKey || event.ctrlKey) && event.key === "1") { 579 event.preventDefault(); 580 searchInputRef.current?.focus(); 581 } 582 } 583 window.addEventListener("keydown", handleShortcut); 584 return ()=>window.removeEventListener("keydown", handleShortcut); 585 }, [ 586 entityId 587 ]); 588 const visibleActivities = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 589 const term = searchTerm.trim().toLowerCase(); 590 if (!term) return activities; 591 return activities.filter((activity)=>{ 592 const haystack = [ 593 activity.title, 594 activity.body, 595 activity.authorName, 596 activity.dealTitle, 597 activity.interactionType 598 ].filter((value)=>typeof value === "string" && value.length > 0).join(" ").toLowerCase(); 599 return haystack.includes(term); 600 }); 601 }, [ 602 activities, 603 searchTerm 604 ]); 605 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 606 onActionChange?.(null); 607 return ()=>onActionChange?.(null); 608 }, [ 609 onActionChange 610 ]); 611 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 612 onLoadingChange?.(loading); 613 }, [ 614 loading, 615 onLoadingChange 616 ]); 617 const loadActivities = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 618 if (!entityId) {
619 setActivities([]); 620 return; 621 } 622 setLoading(true); 623 try { 624 const excludedFilterActive = excludeInteractionType ? filterTypes.includes(excludeInteractionType) : true; 625 const canonicalParams = new URLSearchParams({ 626 entityId, 627 limit: "50", 628 sortField: "occurredAt", 629 sortDir: "desc" 630 }); 631 if (excludeInteractionType && !excludedFilterActive) canonicalParams.set("excludeInteractionType", excludeInteractionType); 632 if (dealId) canonicalParams.set("dealId", dealId); 633 if (filterTypes.length > 0) canonicalParams.set("type", filterTypes.join(",")); 634 if (filterDateFrom) canonicalParams.set("from", filterDateFrom); 635 if (filterDateTo) canonicalParams.set("to", filterDateTo); 636 const canonicalItems = []; 637 let canonicalCursor; 638 let canonicalHasMore = false; 639 let pageIndex = 0; 640 do { 641 const params = new URLSearchParams(canonicalParams); 642 if (canonicalCursor) params.set("cursor", canonicalCursor); 643 const canonicalPayload = await (0, __TURBOPACK__imported__module__490746__["readApiResultOrThrow"])(`/api/customers/interactions?${params.toString()}`).catch(()=>({ 644 items: [], 645 nextCursor: void 0 646 })); 647 canonicalItems.push(...Array.isArray(canonicalPayload?.items) ? canonicalPayload.items : []); 648 canonicalCursor = typeof canonicalPayload?.nextCursor === "string" ? canonicalPayload.nextCursor : void 0; 649 canonicalHasMore = Boolean(canonicalCursor); 650 pageIndex += 1; 651 }while (canonicalCursor && pageIndex < loadedPages) 652 if (useCanonicalInteractions) {
653 setActivities(sortTimelineActivities(canonicalItems)); 654 setHasMore(canonicalHasMore); 655 return; 656 } 657 const legacyPageNumbers = Array.from({ 658 length: loadedPages 659 }, (_, index)=>index + 1); 660 const legacyPayloads = await Promise.all(legacyPageNumbers.map((legacyPage)=>{ 661 const legacyParams = new URLSearchParams({ 662 entityId, 663 page: String(legacyPage), 664 pageSize: "50", 665 sortField: "occurredAt", 666 sortDir: "desc" 667 }); 668 if (dealId) legacyParams.set("dealId", dealId); 669 return (0, __TURBOPACK__imported__module__490746__["readApiResultOrThrow"])(`/api/customers/activities?${legacyParams.toString()}`).catch(()=>({ 670 items: [], 671 totalPages: 1 672 })); 673 })); 674 const legacyItems = []; 675 let legacyTotalPages = 1; 676 for (const legacyPayload of legacyPayloads){ 677 legacyItems.push(...Array.isArray(legacyPayload?.items) ? legacyPayload.items.map(normalizeLegacyActivity) : []); 678 legacyTotalPages = typeof legacyPayload?.totalPages === "number" ? legacyPayload.totalPages : legacyTotalPages; 679 } 680 const legacyFiltered = legacyItems.filter((entry)=>{ 681 if (filterTypes.length > 0 && !filterTypes.includes(entry.interactionType)) return false; 682 const dateOnly = toDateOnly(entry.occurredAt ?? entry.createdAt); 683 if (filterDateFrom && dateOnly < filterDateFrom) return false; 684 if (filterDateTo && dateOnly > filterDateTo) return false; 685 return true; 686 }); 687 const seen = /* @__PURE__ */ new Set(); 688 const merged = []; 689 for (const item of [ 690 ...canonicalItems, 691 ...legacyFiltered 692 ]){ 693 if (!seen.has(item.id)) { 694 seen.add(item.id); 695 merged.push(item); 696 } 697 }
698 setActivities(sortTimelineActivities(merged)); 699 setHasMore(canonicalHasMore || legacyTotalPages > loadedPages); 700 } catch (error) { 701 logger.error("customers.activities.history failed", { 702 err: error 703 }); 704 (0, __TURBOPACK__imported__module__484973__["flash"])(t("customers.activities.loadFailed", "Failed to load activities."), "error"); 705 setActivities([]); 706 setHasMore(false); 707 } finally{ 708 setLoading(false); 709 } 710 }, [ 711 dealId, 712 entityId, 713 excludeInteractionType, 714 filterDateFrom, 715 filterDateTo, 716 filterTypes, 717 loadedPages, 718 useCanonicalInteractions, 719 refreshKey, 720 t 721 ]); 722 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 723 setLoadedPages(1); 724 }, [ 725 dealId, 726 entityId, 727 filterDateFrom, 728 filterDateTo, 729 filterTypes, 730 useCanonicalInteractions 731 ]); 732 const handleMarkDone = __TURBOPACK__imported__module__271645__["useCallback"](async (activityId)=>{ 733 try { 734 const operation = ()=>(0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])("/api/customers/interactions/complete", { 735 method: "POST", 736 headers: { 737 "content-type": "application/json" 738 }, 739 body: JSON.stringify({ 740 id: activityId, 741 occurredAt: /* @__PURE__ */ new Date().toISOString() 742 }) 743 }); 744 if (runGuardedMutation) { 745 await runGuardedMutation(operation, { 746 id: activityId, 747 status: "done", 748 operation: "completeActivity" 749 }); 750 } else { 751 await operation(); 752 } 753 (0, __TURBOPACK__imported__module__484973__["flash"])(t("customers.activities.actions.markDoneSuccess", "Activity marked done"), "success"); 754 await loadActivities(); 755 } catch (err) { 756 logger.warn("Mark done failed", { 757 component: "ActivitiesSection", 758 activityId, 759 err 760 }); 761 (0, __TURBOPACK__imported__module__484973__["flash"])(t("customers.activities.actions.markDoneError", "Could not mark activity as done"), "error"); 762 } 763 }, [ 764 loadActivities, 765 runGuardedMutation, 766 t 767 ]); 768 const resolvedUserIdsRef = __TURBOPACK__imported__module__271645__["useRef"](/* @__PURE__ */ new Set()); 769 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 770 loadActivities().then(()=>{ 771 resolvedUserIdsRef.current = /* @__PURE__ */ new Set(); 772 }).catch((err)=>logger.warn("loadActivities failed", { 773 component: "ActivitiesSection", 774 err 775 })); 776 }, [ 777 loadActivities 778 ]); 779 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 780 const unresolvedIds = /* @__PURE__ */ new Set(); 781 for (const a of activities){ 782 if (a.authorUserId && !a.authorName && !resolvedUserIdsRef.current.has(a.authorUserId)) { 783 unresolvedIds.add(a.authorUserId); 784 } 785 } 786 if (unresolvedIds.size === 0) return; 787 for (const uid of unresolvedIds)resolvedUserIdsRef.current.add(uid); 788 const controller = new AbortController(); 789 (0, __TURBOPACK__imported__module__490746__["readApiResultOrThrow"])(`/api/auth/users?ids=${[ 790 ...unresolvedIds 791 ].join(",")}`, { 792 signal: controller.signal 793 }).then((data)=>{ 794 const users = Array.isArray(data?.items) ? data.items : []; 795 const nameMap = /* @__PURE__ */ new Map(); 796 for (const user of users){ 797 const userId = typeof user.id === "string" ? user.id : null; 798 const name = typeof user.display_name === "string" && user.display_name.trim() ? user.display_name.trim() : typeof user.email === "string" ? user.email : null; 799 if (userId && name) nameMap.set(userId, name); 800 } 801 if (nameMap.size > 0) {
802 setActivities((prev)=>prev.map((a)=>{ 803 if (a.authorUserId && !a.authorName && nameMap.has(a.authorUserId)) { 804 return { 805 ...a, 806 authorName: nameMap.get(a.authorUserId) ?? null 807 }; 808 } 809 return a; 810 })); 811 } 812 }).catch((err)=>logger.warn("resolve author names failed", { 813 component: "ActivitiesSection", 814 err 815 })); 816 return ()=>controller.abort(); 817 }, [ 818 activities 819 ]); 820 const totalCount = activities.length; 821 const visibleCount = visibleActivities.length; 822 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 823 className: "flex flex-col gap-3.5 rounded-[10px] border border-border bg-card pt-4 pb-[18px] px-[18px]", 824 children: [ 825 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 826 className: "flex items-center gap-2", 827 children: [
828 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__503116__["Clock"], { 829 className: "size-[15px] text-muted-foreground" 830 }), 831 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("h3", { 832 className: "text-[13px] font-semibold text-foreground", 833 children: entityName ? t("customers.timeline.history.title", "Interaction history with {{name}}", { 834 name: entityName 835 }) : t("customers.timeline.history.titleGeneric", "Interaction history") 836 }) 837 ] 838 }), 839 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("label", { 840 className: "relative flex items-center", 841 children: [ 842 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__555436__["Search"], { 843 className: "pointer-events-none absolute left-2.5 size-5 text-muted-foreground", 844 "aria-hidden": true 845 }),
846 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("input", { 847 ref: searchInputRef, 848 type: "search", 849 value: searchTerm, 850 onChange: (event)=>setSearchTerm(event.target.value), 851 placeholder: t("customers.timeline.history.searchPlaceholder", "Search..."), 852 "aria-label": t("customers.timeline.history.searchAriaLabel", "Search interaction history"), 853 className: "h-9 w-full rounded-[10px] border border-border bg-card pl-9 pr-14 text-sm text-foreground shadow-xs placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden" 854 }), 855 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__443530__["Kbd"], { 856 className: "pointer-events-none absolute right-2 hidden text-[11px] uppercase tracking-[0.48px] sm:inline-flex", 857 children: "\u23181" 858 }) 859 ] 860 }),
861 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(ActivityTimelineFilters, { 862 entityId, 863 activeTypes: filterTypes, 864 dateFrom: filterDateFrom, 865 dateTo: filterDateTo, 866 onTypesChange: setFilterTypes, 867 onDateFromChange: setFilterDateFrom, 868 onDateToChange: setFilterDateTo, 869 onReset: ()=>{ 870 setFilterTypes([]); 871 setFilterDateFrom(""); 872 setFilterDateTo(""); 873 } 874 }), 875 loading && totalCount === 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 876 className: "rounded-lg border border-dashed border-border/70 px-4 py-8 text-sm text-muted-foreground", 877 children: t("customers.people.detail.activities.loading", "Loading activities\u2026") 878 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 879 children: [
880 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(ActivityTimeline, { 881 activities: visibleActivities, 882 onEdit: onEditActivity, 883 onMarkDone: handleMarkDone 884 }), 885 totalCount > 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 886 className: "flex items-center justify-between gap-3 border-t border-border/60 pt-3", 887 children: [ 888 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 889 className: "text-xs text-muted-foreground", 890 children: searchTerm.trim() ? t("customers.activities.seeMatching", "Showing {visible} of {total} activities", { 891 visible: visibleCount, 892 total: totalCount 893 }) : t("customers.activities.seeAll", "See all {count} activities", { 894 count: totalCount 895 }) 896 }),
897 hasMore ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 898 type: "button", 899 variant: "link", 900 size: "sm", 901 onClick: ()=>setLoadedPages((value)=>value + 1), 902 children: t("customers.activities.loadMore", "Load more") 903 }) : null 904 ] 905 }) : null 906 ] 907 }) 908 ] 909 }); 910} 911var ActivitiesSection_default = ActivitiesSection; 912; 913__turbopack_context__.s([ 914 "ActivitiesSection", 915 0, 916 ActivitiesSection 917], 425961); 918}), 919858632, ((__turbopack_context__) => { 920"use strict"; 921 922var __TURBOPACK__imported__module__490746__ = __turbopack_context__.i(490746); 923var __TURBOPACK__imported__module__977896__ = __turbopack_context__.i(977896); 924var __TURBOPACK__imported__module__54306__ = __turbopack_context__.i(54306); 925"use client"; 926; 927; 928; 929function createCustomerNotesAdapter(translator, options = {}) { 930 const runWrite = async (runner, payload)=>{ 931 if (options.runMutation) { 932 return options.runMutation(runner, payload); 933 } 934 return runner(); 935 }; 936 return { 937 list: async ({ entityId, dealId })=>{ 938 const params = new URLSearchParams(); 939 if (entityId) params.set("entityId", entityId); 940 if (dealId) params.set("dealId", dealId); 941 const payload = await (0, __TURBOPACK__imported__module__490746__["readApiResultOrThrow"])(`/api/customers/comments?${params.toString()}`, void 0, { 942 errorMessage: translator("customers.people.detail.notes.loadError", "Failed to load notes.") 943 }); 944 const items = Array.isArray(payload?.items) ? payload.items : []; 945 return items.map(__TURBOPACK__imported__module__54306__["mapCommentSummary"]); 946 }, 947 listPage: async ({ entityId, dealId, page, pageSize })=>{ 948 const params = new URLSearchParams(); 949 if (entityId) params.set("entityId", entityId); 950 if (dealId) params.set("dealId", dealId); 951 params.set("page", String(page)); 952 params.set("pageSize", String(pageSize)); 953 const payload = await (0, __TURBOPACK__imported__module__490746__["readApiResultOrThrow"])(`/api/customers/comments?${params.toString()}`, void 0, { 954 errorMessage: translator("customers.people.detail.notes.loadError", "Failed to load notes.") 955 }); 956 const items = Array.isArray(payload?.items) ? payload.items.map(__TURBOPACK__imported__module__54306__["mapCommentSummary"]) : []; 957 const total = typeof payload?.total === "number" ? payload.total : items.length; 958 const totalPages = typeof payload?.totalPages === "number" ? payload.totalPages : Math.max(1, Math.ceil(total / pageSize)); 959 const resolvedPage = typeof payload?.page === "number" ? payload.page : page; 960 const resolvedPageSize = typeof payload?.pageSize === "number" ? payload.pageSize : pageSize; 961 return { 962 items, 963 total, 964 page: resolvedPage, 965 pageSize: resolvedPageSize, 966 totalPages 967 }; 968 }, 969 create: async ({ entityId, body, appearanceIcon, appearanceColor, dealId })=>{ 970 const requestBody = { 971 entityId, 972 body, 973 appearanceIcon: appearanceIcon ?? void 0, 974 appearanceColor: appearanceColor ?? void 0, 975 dealId: dealId ?? void 0 976 }; 977 const response = await runWrite(()=>(0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])("/api/customers/comments", { 978 method: "POST", 979 headers: { 980 "content-type": "application/json" 981 }, 982 body: JSON.stringify(requestBody) 983 }, { 984 errorMessage: translator("customers.people.detail.notes.error") 985 }), { 986 operation: "createNote", 987 entityId, 988 dealId: dealId ?? null 989 }); 990 return response.result ?? {}; 991 }, 992 update: async ({ id, patch, updatedAt })=>{ 993 const payload = { 994 id 995 }; 996 if (patch.body !== void 0) payload.body = patch.body; 997 if (patch.appearanceIcon !== void 0) payload.appearanceIcon = patch.appearanceIcon; 998 if (patch.appearanceColor !== void 0) payload.appearanceColor = patch.appearanceColor; 999 await runWrite(()=>(0, __TURBOPACK__imported__module__490746__["withScopedApiRequestHeaders"])((0, __TURBOPACK__imported__module__977896__["buildOptimisticLockHeader"])(updatedAt ?? null), ()=>(0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])("/api/customers/comments", { 1000 method: "PUT", 1001 headers: { 1002 "content-type": "application/json" 1003 }, 1004 body: JSON.stringify(payload) 1005 }, { 1006 errorMessage: translator("customers.people.detail.notes.updateError") 1007 })), { 1008 operation: "updateNote", 1009 id 1010 }); 1011 }, 1012 delete: async ({ id, updatedAt })=>{ 1013 await runWrite(()=>(0, __TURBOPACK__imported__module__490746__["withScopedApiRequestHeaders"])((0, __TURBOPACK__imported__module__977896__["buildOptimisticLockHeader"])(updatedAt ?? null), ()=>(0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])(`/api/customers/comments?id=${encodeURIComponent(id)}`, { 1014 method: "DELETE", 1015 headers: { 1016 "content-type": "application/json" 1017 } 1018 }, { 1019 errorMessage: translator("customers.people.detail.notes.deleteError", "Failed to delete note") 1020 })), { 1021 operation: "deleteNote", 1022 id 1023 }); 1024 } 1025 }; 1026} 1027; 1028__turbopack_context__.s([ 1029 "createCustomerNotesAdapter", 1030 0, 1031 createCustomerNotesAdapter 1032]); 1033}), 1034692925, ((__turbopack_context__) => { 1035"use strict"; 1036 1037var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 1038var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 1039var __TURBOPACK__imported__module__475503__ = __turbopack_context__.i(475503); 1040var __TURBOPACK__imported__module__637683__ = __turbopack_context__.i(637683); 1041var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 1042var __TURBOPACK__imported__module__490746__ = __turbopack_context__.i(490746); 1043var __TURBOPACK__imported__module__484973__ = __turbopack_context__.i(484973); 1044var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 1045"use client"; 1046; 1047; 1048; 1049; 1050; 1051; 1052;
1053function TagsSection({ entityId, tags, onChange, isSubmitting = false, title, controllerRef }) { 1054 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1055 const fetchTags = __TURBOPACK__imported__module__271645__["useCallback"](async (query)=>{ 1056 const params = new URLSearchParams({ 1057 pageSize: "100" 1058 }); 1059 if (query) params.set("search", query); 1060 const payload = await (0, __TURBOPACK__imported__module__490746__["readApiResultOrThrow"])(`/api/customers/tags?${params.toString()}`, void 0, { 1061 errorMessage: t("customers.people.detail.tags.loadError", "Failed to load tags.") 1062 }); 1063 const items = Array.isArray(payload?.items) ? payload.items : []; 1064 return items.map((item)=>{ 1065 if (!item || typeof item !== "object") return null; 1066 const raw = item; 1067 const rawId = typeof raw.id === "string" ? raw.id : typeof raw.tagId === "string" ? raw.tagId : null; 1068 if (!rawId) return null; 1069 const labelValue = typeof raw.label === "string" && raw.label.trim().length && raw.label.trim() || typeof raw.slug === "string" && raw.slug.trim().length && raw.slug.trim() || rawId; 1070 const color = typeof raw.color === "string" && raw.color.trim().length ? raw.color.trim() : null; 1071 return { 1072 id: rawId, 1073 label: labelValue, 1074 color 1075 }; 1076 }).filter((value)=>value !== null); 1077 }, [ 1078 t 1079 ]); 1080 const createTag = __TURBOPACK__imported__module__271645__["useCallback"](async (label)=>{ 1081 const trimmed = label.trim(); 1082 if (!trimmed.length) { 1083 throw new Error(t("customers.people.detail.tags.labelRequired", "Tag name is required.")); 1084 } 1085 const response = await (0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])("/api/customers/tags", { 1086 method: "POST", 1087 headers: { 1088 "content-type": "application/json" 1089 }, 1090 body: JSON.stringify({ 1091 label: trimmed, 1092 slug: (0, __TURBOPACK__imported__module__406911__["slugifyTagLabel"])(trimmed) 1093 }) 1094 }, { 1095 errorMessage: t("customers.people.detail.tags.createError", "Failed to create tag.") 1096 }); 1097 const payload = response.result ?? {}; 1098 const id = typeof payload?.id === "string" ? payload.id : typeof payload?.tagId === "string" ? payload.tagId : ""; 1099 if (!id) throw new Error(t("customers.people.detail.tags.createError", "Failed to create tag.")); 1100 const color = typeof payload?.color === "string" && payload.color.trim().length ? payload.color.trim() : null; 1101 return { 1102 id, 1103 label: trimmed, 1104 color 1105 }; 1106 }, [ 1107 t 1108 ]); 1109 const assignTag = __TURBOPACK__imported__module__271645__["useCallback"](async (tagId)=>{ 1110 if (!entityId) return; 1111 await (0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])("/api/customers/tags/assign", { 1112 method: "POST", 1113 headers: { 1114 "content-type": "application/json" 1115 }, 1116 body: JSON.stringify({ 1117 tagId, 1118 entityId 1119 }) 1120 }, { 1121 errorMessage: t("customers.people.detail.tags.assignError", "Failed to assign tag.") 1122 }); 1123 }, [ 1124 entityId, 1125 t 1126 ]); 1127 const unassignTag = __TURBOPACK__imported__module__271645__["useCallback"](async (tagId)=>{ 1128 if (!entityId) return; 1129 await (0, __TURBOPACK__imported__module__490746__["apiCallOrThrow"])("/api/customers/tags/unassign", { 1130 method: "POST", 1131 headers: { 1132 "content-type": "application/json" 1133 }, 1134 body: JSON.stringify({ 1135 tagId, 1136 entityId 1137 }) 1138 }, { 1139 errorMessage: t("customers.people.detail.tags.unassignError", "Failed to remove tag.") 1140 }); 1141 }, [ 1142 entityId, 1143 t 1144 ]); 1145 const handlePersist = __TURBOPACK__imported__module__271645__["useCallback"](async ({ added, removed })=>{ 1146 for (const tag of added){ 1147 await assignTag(tag.id); 1148 } 1149 for (const tag of removed){ 1150 await unassignTag(tag.id); 1151 } 1152 (0, __TURBOPACK__imported__module__484973__["flash"])(t("customers.people.detail.tags.success", "Tags updated."), "success"); 1153 }, [ 1154 assignTag, 1155 t, 1156 unassignTag 1157 ]); 1158 const labels = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 1159 loading: t("customers.people.detail.tags.loading", "Loading tags\u2026"), 1160 placeholder: t("customers.people.detail.tags.placeholder", "Type to add tags"), 1161 empty: t("customers.people.detail.empty.tags"), 1162 loadError: t("customers.people.detail.tags.loadError", "Failed to load tags."), 1163 createError: t("customers.people.detail.tags.createError", "Failed to create tag."), 1164 updateError: t("customers.people.detail.tags.error", "Failed to update tags."), 1165 labelRequired: t("customers.people.detail.tags.labelRequired", "Tag name is required."), 1166 saveShortcut: t("customers.people.detail.tags.saveShortcut", "Save \u2318\u23CE / Ctrl+Enter"), 1167 cancelShortcut: t("customers.people.detail.tags.cancelShortcut", "Cancel (Esc)"), 1168 edit: t("ui.forms.actions.edit"), 1169 cancel: t("ui.forms.actions.cancel"), 1170 success: t("customers.people.detail.tags.success", "Tags updated."), 1171 saving: t("ui.forms.status.saving", "Saving\u2026"), 1172 autoSaveHint: t("customers.people.detail.tags.autoSaveHint", "Tags save automatically after each change.") 1173 }), [ 1174 t 1175 ]); 1176 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__637683__["TagsSection"], { 1177 title: title ?? t("customers.people.detail.sections.tags"), 1178 tags, 1179 onChange, 1180 isSubmitting, 1181 canEdit: !!entityId, 1182 autoSave: true, 1183 controllerRef, 1184 loadOptions: fetchTags, 1185 createTag, 1186 onSave: handlePersist, 1187 labels 1188 }); 1189} 1190var TagsSection_default = TagsSection; 1191; 1192__turbopack_context__.s([ 1193 "TagsSection", 1194 0, 1195 TagsSection 1196]); 1197}), 1198427372, ((__turbopack_context__) => { 1199"use strict"; 1200 1201var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 1202var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 1203var __TURBOPACK__imported__module__475503__ = __turbopack_context__.i(475503); 1204var __TURBOPACK__imported__module__113601__ = __turbopack_context__.i(113601); 1205var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 1206"use client"; 1207; 1208; 1209; 1210; 1211function CustomDataSection(props) { 1212 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1213 const labels = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 1214 loading: t("customers.people.detail.loading"), 1215 emptyValue: t("customers.people.detail.noValue"), 1216 noFields: t("entities.customFields.empty"), 1217 defineFields: t("customers.people.detail.customFields.defineFirst"), 1218 saveShortcut: t("customers.people.detail.inline.saveShortcut"), 1219 edit: t("ui.forms.actions.edit"), 1220 cancel: t("ui.forms.actions.cancel") 1221 }), [ 1222 t 1223 ]); 1224 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__113601__["CustomDataSection"], { 1225 ...props, 1226 labels 1227 }); 1228} 1229var CustomDataSection_default = CustomDataSection; 1230; 1231__turbopack_context__.s([ 1232 "CustomDataSection", 1233 0, 1234 CustomDataSection 1235]); 1236}), 1237653278, ((__turbopack_context__) => { 1238"use strict"; 1239 1240var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 1241var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 1242var __TURBOPACK__imported__module__522016__ = __turbopack_context__.i(522016); 1243var __TURBOPACK__imported__module__257995__ = __turbopack_context__.i(257995); 1244var __TURBOPACK__imported__module__63727__ = __turbopack_context__.i(63727); 1245var __TURBOPACK__imported__module__531278__ = __turbopack_context__.i(531278); 1246var __TURBOPACK__imported__module__788699__ = __turbopack_context__.i(788699); 1247var __TURBOPACK__imported__module__37727__ = __turbopack_context__.i(37727); 1248var __TURBOPACK__imported__module__110035__ = __turbopack_context__.i(110035); 1249var __TURBOPACK__imported__module__441233__ = __turbopack_context__.i(441233); 1250var __TURBOPACK__imported__module__98336__ = __turbopack_context__.i(98336); 1251var __TURBOPACK__imported__module__484973__ = __turbopack_context__.i(484973); 1252var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 1253var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 1254var __TURBOPACK__imported__module__912598__ = __turbopack_context__.i(912598); 1255var __TURBOPACK__imported__module__477315__ = __turbopack_context__.i(477315); 1256var __TURBOPACK__imported__module__937095__ = __turbopack_context__.i(937095); 1257var __TURBOPACK__imported__module__790415__ = __turbopack_context__.i(790415); 1258var __TURBOPACK__imported__module__12344__ = __turbopack_context__.i(12344); 1259var __TURBOPACK__imported__module__10697__ = __turbopack_context__.i(10697); 1260var __TURBOPACK__imported__module__158715__ = __turbopack_context__.i(158715); 1261var __TURBOPACK__imported__module__203310__ = __turbopack_context__.i(203310); 1262var __TURBOPACK__imported__module__867457__ = __turbopack_context__.i(867457); 1263var __TURBOPACK__imported__module__445106__ = __turbopack_context__.i(445106); 1264var __TURBOPACK__imported__module__207623__ = __turbopack_context__.i(207623); 1265var __TURBOPACK__imported__module__852674__ = __turbopack_context__.i(852674); 1266"use client"; 1267; 1268; 1269; 1270; 1271; 1272; 1273; 1274; 1275; 1276; 1277; 1278; 1279; 1280; 1281; 1282; 1283; 1284; 1285; 1286; 1287function InlineTextEditor(props) { 1288 const { type = "text", validator, recordId } = props; 1289 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1290 const normalizeText = __TURBOPACK__imported__module__271645__["useCallback"]((value)=>{ 1291 if (typeof value === "string") return value; 1292 if (value === null || value === void 0) return ""; 1293 return String(value); 1294 }, []); 1295 const [draft, setDraft] = __TURBOPACK__imported__module__271645__["useState"](()=>normalizeText(props.value)); 1296 const setDraftValue = __TURBOPACK__imported__module__271645__["useCallback"]((value)=>{ 1297 setDraft(normalizeText(value)); 1298 }, [ 1299 normalizeText 1300 ]); 1301 const [editing, setEditing] = __TURBOPACK__imported__module__271645__["useState"](false); 1302 const currentRecordId = __TURBOPACK__imported__module__271645__["useMemo"](()=>typeof recordId === "string" ? recordId : null, [ 1303 recordId 1304 ]); 1305 const isEmailField = type === "email"; 1306 const isPhoneField = type === "tel"; 1307 const trimmedDraft = __TURBOPACK__imported__module__271645__["useMemo"](()=>draft.trim(), [ 1308 draft 1309 ]); 1310 const validationError = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 1311 if (!validator) return null; 1312 return validator(trimmedDraft); 1313 }, [ 1314 trimmedDraft, 1315 validator 1316 ]); 1317 const isValidEmailForLookup = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 1318 if (!isEmailField) return false;
1319 if (!trimmedDraft.length) return false; 1320 return !validationError; 1321 }, [ 1322 isEmailField, 1323 trimmedDraft, 1324 validationError 1325 ]); 1326 const { duplicate: emailDuplicate, checking: emailChecking } = (0, __TURBOPACK__imported__module__937095__["useEmailDuplicateCheck"])(draft, { 1327 recordId: currentRecordId, 1328 disabled: !editing || !isValidEmailForLookup, 1329 matchMode: "prefix" 1330 }); 1331 const [phoneDuplicate, setPhoneDuplicate] = __TURBOPACK__imported__module__271645__["useState"](null); 1332 const [phoneChecking, setPhoneChecking] = __TURBOPACK__imported__module__271645__["useState"](false); 1333 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 1334 if (!editing) { 1335 setDraftValue(props.value); 1336 } 1337 }, [ 1338 editing, 1339 props.value, 1340 setDraftValue 1341 ]); 1342 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 1343 if (!editing || !isPhoneField) { 1344 setPhoneDuplicate(null); 1345 setPhoneChecking(false); 1346 return; 1347 } 1348 const digits = draft.replace(/\\D/g, ""); 1349 if (digits.length < 7) { 1350 setPhoneDuplicate(null); 1351 setPhoneChecking(false); 1352 return; 1353 } 1354 let cancelled = false; 1355 setPhoneChecking(true); 1356 void (0, __TURBOPACK__imported__module__790415__["lookupPhoneDuplicate"])(digits, { 1357 recordId: currentRecordId 1358 }).then((result)=>{ 1359 if (cancelled) return; 1360 setPhoneDuplicate(result); 1361 }).catch(()=>{ 1362 if (cancelled) return; 1363 setPhoneDuplicate(null); 1364 }).finally(()=>{ 1365 if (cancelled) return; 1366 setPhoneChecking(false); 1367 }); 1368 return ()=>{ 1369 cancelled = true; 1370 }; 1371 }, [ 1372 currentRecordId, 1373 draft, 1374 editing, 1375 isPhoneField 1376 ]); 1377 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__12344__["InlineTextEditor"], { 1378 ...props, 1379 type, 1380 validator, 1381 value: normalizeText(props.value), 1382 onDraftChange: setDraftValue, 1383 onEditingChange: setEditing, 1384 renderBelowInput: ({ resolvedType, error })=>{ 1385 if (resolvedType === "email") { 1386 if (error || !editing || !isValidEmailForLookup) return null; 1387 if (emailDuplicate) { 1388 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("p", { 1389 className: "text-xs text-muted-foreground", 1390 children: [ 1391 t("customers.people.detail.inline.emailDuplicate", void 0, { 1392 name: emailDuplicate.displayName 1393 }), 1394 " ",
1395 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__522016__["default"], { 1396 className: "font-medium text-primary underline underline-offset-2", 1397 href: `/backend/customers/people-v2/${emailDuplicate.id}`, 1398 children: t("customers.people.detail.inline.emailDuplicateLink") 1399 }) 1400 ] 1401 }); 1402 } 1403 if (emailChecking) { 1404 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1405 className: "text-xs text-muted-foreground", 1406 children: t("customers.people.detail.inline.emailChecking") 1407 }); 1408 } 1409 } 1410 if (resolvedType === "tel") { 1411 if (error || !editing) return null; 1412 if (phoneDuplicate) { 1413 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("p", { 1414 className: "text-xs text-muted-foreground", 1415 children: [ 1416 t("customers.people.form.phoneDuplicateNotice", void 0, { 1417 name: phoneDuplicate.label 1418 }), 1419 " ", 1420 phoneDuplicate.href ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__522016__["default"], { 1421 className: "font-medium text-primary underline underline-offset-2", 1422 href: phoneDuplicate.href, 1423 children: t("customers.people.form.phoneDuplicateLink") 1424 }) : null 1425 ] 1426 }); 1427 } 1428 if (phoneChecking) { 1429 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1430 className: "text-xs text-muted-foreground", 1431 children: t("customers.people.form.phoneChecking") 1432 }); 1433 } 1434 } 1435 return null; 1436 } 1437 }); 1438} 1439const InlineMultilineEditor = __TURBOPACK__imported__module__12344__["InlineMultilineEditor"]; 1440const InlineSelectEditor = __TURBOPACK__imported__module__12344__["InlineSelectEditor"]; 1441function createSocialRenderDisplay(IconComponent) { 1442 return ({ value, emptyLabel })=>{ 1443 const raw = typeof value === "string" ? value.trim() : ""; 1444 if (!raw.length) { 1445 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1446 className: "text-sm text-muted-foreground", 1447 children: emptyLabel 1448 }); 1449 } 1450 const display = raw.replace(/^https?:\/\/(www\.)?/i, "").replace(/\/$/, ""); 1451 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("a", { 1452 className: "inline-flex items-center gap-2 text-sm text-primary hover:text-primary/90 hover:underline", 1453 href: raw, 1454 target: "_blank", 1455 rel: "noreferrer", 1456 children: [
1457 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(IconComponent, { 1458 "aria-hidden": true, 1459 className: "h-4 w-4" 1460 }), 1461 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1462 className: "truncate", 1463 children: display 1464 }) 1465 ] 1466 }); 1467 }; 1468} 1469const renderLinkedInDisplay = createSocialRenderDisplay(__TURBOPACK__imported__module__63727__["Briefcase"]); 1470const renderTwitterDisplay = createSocialRenderDisplay(__TURBOPACK__imported__module__257995__["AtSign"]); 1471const renderMultilineMarkdownDisplay = ({ value, emptyLabel })=>{ 1472 const raw = typeof value === "string" ? value : ""; 1473 const trimmed = raw.trim(); 1474 if (!trimmed.length) { 1475 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1476 className: "text-muted-foreground", 1477 children: emptyLabel 1478 }); 1479 } 1480 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__98336__["MarkdownContent"], { 1481 format: "markdown", 1482 body: raw, 1483 className: "text-sm text-foreground [&>*]:mb-2 [&>*:last-child]:mb-0 [&_ul]:ml-4 [&_ul]:list-disc [&_ol]:ml-4 [&_ol]:list-decimal [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_pre]:rounded-md [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:text-xs" 1484 }); 1485}; 1486function InlineDictionaryEditor({ label, value, emptyLabel, onSave, kind, variant = "default", activateOnClick = false, containerClassName, triggerClassName, selectClassName }) { 1487 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1488 const queryClient = (0, __TURBOPACK__imported__module__912598__["useQueryClient"])(); 1489 const translate = __TURBOPACK__imported__module__271645__["useCallback"]((key, fallback)=>{ 1490 const result = t(key); 1491 return result === key ? fallback : result; 1492 }, [ 1493 t 1494 ]); 1495 const dictionaryLabels = __TURBOPACK__imported__module__271645__["useMemo"](()=>(0, __TURBOPACK__imported__module__445106__["createDictionarySelectLabels"])(kind, translate), [ 1496 kind, 1497 translate 1498 ]); 1499 const scopeVersion = (0, __TURBOPACK__imported__module__477315__["useOrganizationScopeVersion"])(); 1500 const dictionaryQuery = (0, __TURBOPACK__imported__module__852674__["useCustomerDictionary"])(kind, scopeVersion); 1501 const dictionaryMap = dictionaryQuery.data?.map ?? null; 1502 const selectOptions = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 1503 if (!dictionaryMap) return []; 1504 return Object.values(dictionaryMap).map((entry)=>({ 1505 value: entry.value, 1506 label: entry.label 1507 })); 1508 }, [ 1509 dictionaryMap 1510 ]); 1511 const handleSave = __TURBOPACK__imported__module__271645__["useCallback"](async (nextValue)=>{ 1512 try { 1513 await onSave(nextValue); 1514 await (0, __TURBOPACK__imported__module__852674__["invalidateCustomerDictionary"])(queryClient, kind); 1515 } catch (err) { 1516 const message = err instanceof Error ? err.message : t("customers.people.detail.inline.error"); 1517 (0, __TURBOPACK__imported__module__484973__["flash"])(message, "error"); 1518 } 1519 }, [ 1520 kind, 1521 onSave, 1522 queryClient, 1523 t 1524 ]); 1525 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__12344__["InlineSelectEditor"], { 1526 label, 1527 value, 1528 emptyLabel, 1529 options: selectOptions, 1530 onSave: handleSave, 1531 variant, 1532 activateOnClick, 1533 containerClassName, 1534 triggerClassName, 1535 hideLabel: false, 1536 renderEditor: ({ value: selectValue, onChange })=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 1537 children: [
1538 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__203310__["DictionarySelectField"], { 1539 kind, 1540 value: selectValue.length ? selectValue : void 0, 1541 onChange: (next)=>onChange(next ?? ""), 1542 labels: dictionaryLabels, 1543 selectClassName 1544 }), 1545 dictionaryQuery.isError ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1546 className: "text-xs text-status-error-text", 1547 children: dictionaryQuery.error instanceof Error ? dictionaryQuery.error.message : translate("customers.people.form.dictionary.errorLoad", "Failed to load options") 1548 }) : null 1549 ] 1550 }), 1551 renderDisplay: ({ value: currentValue })=>{ 1552 if (dictionaryMap) { 1553 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__158715__["DictionaryValue"], { 1554 value: currentValue, 1555 map: dictionaryMap, 1556 fallback: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1557 className: "text-sm text-muted-foreground", 1558 children: emptyLabel 1559 }), 1560 className: "text-sm", 1561 iconWrapperClassName: "inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card", 1562 iconClassName: "h-4 w-4", 1563 colorClassName: "h-3 w-3 rounded-full" 1564 }); 1565 } 1566 if (currentValue && currentValue.length) { 1567 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1568 className: "break-words text-sm", 1569 children: currentValue 1570 }); 1571 } 1572 if (dictionaryQuery.isLoading) { 1573 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1574 className: "text-sm text-muted-foreground", 1575 children: translate("customers.people.form.dictionary.loading", "Loading\u2026") 1576 }); 1577 } 1578 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1579 className: "text-sm text-muted-foreground", 1580 children: emptyLabel 1581 }); 1582 } 1583 }); 1584} 1585function InlineNextInteractionEditor({ label, valueAt, valueName, valueRefId, valueIcon, valueColor, emptyLabel, onSave, activateOnClick = false }) { 1586 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1587 const [editing, setEditing] = __TURBOPACK__imported__module__271645__["useState"](false); 1588 const [draftDate, setDraftDate] = __TURBOPACK__imported__module__271645__["useState"](()=>valueAt ? valueAt.slice(0, 16) : ""); 1589 const [draftName, setDraftName] = __TURBOPACK__imported__module__271645__["useState"](valueName ?? ""); 1590 const [draftRefId, setDraftRefId] = __TURBOPACK__imported__module__271645__["useState"](valueRefId ?? ""); 1591 const [draftIcon, setDraftIcon] = __TURBOPACK__imported__module__271645__["useState"](valueIcon ?? ""); 1592 const [draftColor, setDraftColor] = __TURBOPACK__imported__module__271645__["useState"](valueColor ?? null); 1593 const [dateError, setDateError] = __TURBOPACK__imported__module__271645__["useState"](null); 1594 const [nameError, setNameError] = __TURBOPACK__imported__module__271645__["useState"](null); 1595 const [submitError, setSubmitError] = __TURBOPACK__imported__module__271645__["useState"](null); 1596 const [saving, setSaving] = __TURBOPACK__imported__module__271645__["useState"](false); 1597 const formRef = __TURBOPACK__imported__module__271645__["useRef"](null); 1598 const dateErrorId = __TURBOPACK__imported__module__271645__["useId"](); 1599 const nameErrorId = __TURBOPACK__imported__module__271645__["useId"](); 1600 const containerClasses = (0, __TURBOPACK__imported__module__406911__["cn"])("group relative rounded-lg border p-4", activateOnClick && !editing ? "curs
1600or-pointer" : null); 1601 const requiredMessage = __TURBOPACK__imported__module__271645__["useMemo"](()=>t("customers.people.detail.inline.required", "This field is required"), [ 1602 t 1603 ]); 1604 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 1605 if (!editing) { 1606 setDraftDate(valueAt ? valueAt.slice(0, 16) : ""); 1607 setDraftName(valueName ?? ""); 1608 setDraftRefId(valueRefId ?? ""); 1609 setDraftIcon(valueIcon ?? ""); 1610 setDraftColor(valueColor ?? null); 1611 setDateError(null); 1612 setNameError(null); 1613 setSubmitError(null); 1614 } 1615 }, [ 1616 editing, 1617 valueAt, 1618 valueName, 1619 valueRefId, 1620 valueIcon, 1621 valueColor 1622 ]); 1623 const appearanceLabels = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 1624 colorLabel: t("customers.people.detail.inline.nextInteractionColorLabel"), 1625 colorHelp: t("customers.people.detail.inline.nextInteractionColorHelp"), 1626 colorClearLabel: t("customers.people.detail.inline.nextInteractionColorClear"), 1627 iconLabel: t("customers.people.detail.inline.nextInteractionIconLabel"), 1628 iconPlaceholder: t("customers.people.detail.inline.nextInteractionIconPlaceholder"), 1629 iconPickerTriggerLabel: t("customers.people.detail.inline.nextInteractionIconBrowse"), 1630 iconSearchPlaceholder: t("customers.people.detail.inline.nextInteractionIconSearchPlaceholder"), 1631 iconSearchEmptyLabel: t("customers.people.detail.inline.nextInteractionIconSearchEmpty"), 1632 iconSuggestionsLabel: t("customers.people.detail.inline.nextInteractionIconSuggestions"), 1633 iconClearLabel: t("customers.people.detail.inline.nextInteractionIconClear"), 1634 previewEmptyLabel: t("customers.people.detail.inline.nextInteractionAppearanceEmpty") 1635 }), [ 1636 t 1637 ]); 1638 const handleSave = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 1639 setSubmitError(null); 1640 setDateError(null); 1641 setNameError(null); 1642 const trimmedName = draftName.trim(); 1643 let hasError = false; 1644 if (!draftDate) { 1645 setDateError(requiredMessage); 1646 hasError = true; 1647 } 1648 if (!trimmedName.length) { 1649 setNameError(requiredMessage); 1650 hasError = true; 1651 } 1652 if (hasError) return; 1653 const parsedDate = new Date(draftDate); 1654 if (Number.isNaN(parsedDate.getTime())) { 1655 setDateError(t("customers.people.detail.inline.nextInteractionInvalid")); 1656 return; 1657 } 1658 const iso = parsedDate.toISOString(); 1659 const trimmedRef = draftRefId.trim(); 1660 const trimmedIcon = draftIcon.trim(); 1661 const normalizedColor = (()=>{ 1662 if (!draftColor) return null; 1663 const trimmed = draftColor.trim().toLowerCase(); 1664 return /^#([0-9a-f]{6})$/.test(trimmed) ? trimmed : null; 1665 })(); 1666 setSaving(true); 1667 try { 1668 await onSave({ 1669 at: iso, 1670 name: trimmedName, 1671 refId: trimmedRef.length ? trimmedRef : null, 1672 icon: trimmedIcon.length ? trimmedIcon : null, 1673 color: normalizedColor 1674 }); 1675 setEditing(false); 1676 } catch (err) { 1677 const message = err instanceof Error ? err.message : t("customers.people.detail.inline.error"); 1678 setSubmitError(message); 1679 } finally{ 1680 setSaving(false); 1681 } 1682 }, [ 1683 draftColor, 1684 draftDate, 1685 draftIcon, 1686 draftName, 1687 draftRefId, 1688 onSave, 1689 requiredMessage, 1690 t 1691 ]); 1692 const handleFormSubmit = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1693 event.preventDefault(); 1694 if (saving) return; 1695 void handleSave(); 1696 }, [ 1697 handleSave, 1698 saving 1699 ]); 1700 const handleFormKeyDown = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1701 if (event.key === "Escape") { 1702 event.preventDefault(); 1703 setEditing(false); 1704 return; 1705 } 1706 if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) { 1707 event.preventDefault(); 1708 if (saving) return; 1709 try { 1710 formRef.current?.requestSubmit(); 1711 } catch { 1712 void handleSave(); 1713 } 1714 } 1715 }, [ 1716 handleSave, 1717 saving 1718 ]); 1719 const handleActivate = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 1720 if (!editing) setEditing(true); 1721 }, [ 1722 editing 1723 ]); 1724 const handleKeyDown = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1725 if (!activateOnClick || editing) return; 1726 if (event.key === "Enter" || event.key === " ") { 1727 event.preventDefault(); 1728 handleActivate(); 1729 } 1730 }, [ 1731 activateOnClick, 1732 editing, 1733 handleActivate 1734 ]); 1735 const handleInteractiveClick = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1736 if (!activateOnClick || editing) return; 1737 const target = event.target; 1738 const interactiveElement = target.closest('button, input, select, textarea, a, [role="link"]'); 1739 if (interactiveElement) { 1740 if (interactiveElement.tagName.toLowerCase() === "a") { 1741 if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { 1742 return; 1743 } 1744 event.preventDefault(); 1745 } else { 1746 return; 1747 } 1748 } 1749 handleActivate(); 1750 }, [ 1751 activateOnClick, 1752 editing, 1753 handleActivate 1754 ]); 1755 const interactiveProps = activateOnClick && !editing ? { 1756 role: "button", 1757 tabIndex: 0, 1758 onClick: handleInteractiveClick, 1759 onKeyDown: handleKeyDown 1760 } : {}; 1761 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1762 className: containerClasses, 1763 onClick: handleInteractiveClick, 1764 children: [
1765 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 1766 type: "button", 1767 variant: "ghost", 1768 size: "sm", 1769 className: (0, __TURBOPACK__imported__module__406911__["cn"])("absolute right-3 top-3 transition-opacity duration-150", editing ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100"), 1770 onClick: (event)=>{ 1771 event.stopPropagation(); 1772 setEditing((state)=>!state); 1773 }, 1774 children: editing ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__37727__["X"], { 1775 className: "h-4 w-4" 1776 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__788699__["Pencil"], { 1777 className: "h-4 w-4" 1778 }) 1779 }),
1780 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1781 className: "flex items-start gap-2", 1782 ...interactiveProps, 1783 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1784 className: "flex-1", 1785 children: [ 1786 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1787 className: "text-xs uppercase tracking-wide text-muted-foreground", 1788 children: label 1789 }), 1790 editing ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("form", { 1791 ref: formRef, 1792 className: "mt-2 space-y-4", 1793 onSubmit: handleFormSubmit, 1794 onKeyDown: handleFormKeyDown, 1795 children: [ 1796 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("input", { 1797 type: "datetime-local", 1798 className: (0, __TURBOPACK__imported__module__406911__["cn"])("w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", dateError ? "border-destructive aria-invalid:border-destructive aria-invalid:ring-destructive" : null), 1799 value: draftDate, 1800 "aria-invalid": dateError ? "true" : void 0, 1801 "aria-required": "true", 1802 "aria-describedby": dateError ? dateErrorId : void 0, 1803 onChange: (event)=>{ 1804 if (dateError) setDateError(null); 1805 if (submitError) setSubmitError(null); 1806 setDraftDate(event.target.value); 1807 } 1808 }), 1809 dateError ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1810 id: dateErrorId, 1811 className: "text-xs text-destructive", 1812 children: dateError 1813 }) : null,
1814 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("input", { 1815 placeholder: t("customers.people.detail.inline.nextInteractionName"), 1816 className: (0, __TURBOPACK__imported__module__406911__["cn"])("w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", nameError ? "border-destructive aria-invalid:border-destructive aria-invalid:ring-destructive" : null), 1817 value: draftName, 1818 "aria-invalid": nameError ? "true" : void 0, 1819 "aria-required": "true", 1820 "aria-describedby": nameError ? nameErrorId : void 0, 1821 onChange: (event)=>{ 1822 if (submitError) setSubmitError(null); 1823 if (nameError) setNameError(null); 1824 setDraftName(event.target.value); 1825 } 1826 }), 1827 nameError ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1828 id: nameErrorId, 1829 className: "text-xs text-destructive", 1830 children: nameError 1831 }) : null,
1832 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("input", { 1833 placeholder: t("customers.people.detail.inline.nextInteractionRef"), 1834 className: "w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", 1835 value: draftRefId, 1836 onChange: (event)=>{ 1837 if (submitError) setSubmitError(null); 1838 setDraftRefId(event.target.value); 1839 } 1840 }), 1841 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__867457__["AppearanceSelector"], { 1842 icon: draftIcon || null, 1843 color: draftColor, 1844 onIconChange: (next)=>{ 1845 if (submitError) setSubmitError(null); 1846 setDraftIcon(next ?? ""); 1847 }, 1848 onColorChange: (next)=>{ 1849 if (submitError) setSubmitError(null); 1850 setDraftColor(next); 1851 }, 1852 iconSuggestions: __TURBOPACK__imported__module__158715__["ICON_SUGGESTIONS"], 1853 disabled: saving, 1854 labels: appearanceLabels 1855 }), 1856 submitError && !dateError && !nameError ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1857 className: "text-xs text-destructive", 1858 children: submitError 1859 }) : null,
1860 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1861 className: "flex flex-wrap items-center gap-2", 1862 children: [ 1863 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__110035__["Button"], { 1864 type: "submit", 1865 size: "sm", 1866 disabled: saving, 1867 children: [ 1868 saving ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__531278__["Loader2"], { 1869 className: "mr-2 h-3.5 w-3.5 animate-spin" 1870 }) : null, 1871 t("customers.people.detail.inline.saveShortcut", "Save \u2318\u23CE / Ctrl+Enter") 1872 ] 1873 }),
1874 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 1875 type: "button", 1876 size: "sm", 1877 variant: "ghost", 1878 onClick: ()=>setEditing(false), 1879 disabled: saving, 1880 children: t("customers.people.detail.inline.cancel") 1881 }), 1882 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 1883 type: "button", 1884 size: "sm", 1885 variant: "secondary", 1886 onClick: async ()=>{ 1887 setDraftDate(""); 1888 setDraftName(""); 1889 setDraftRefId(""); 1890 setDraftIcon(""); 1891 setDraftColor(null); 1892 setDateError(null); 1893 setNameError(null); 1894 setSubmitError(null); 1895 setSaving(true); 1896 try { 1897 await onSave(null); 1898 setEditing(false); 1899 } catch (err) { 1900 const message = err instanceof Error ? err.message : t("customers.people.detail.inline.error"); 1901 setSubmitError(message); 1902 } finally{ 1903 setSaving(false); 1904 } 1905 }, 1906 disabled: saving, 1907 children: t("customers.people.detail.inline.clear") 1908 }) 1909 ] 1910 }) 1911 ] 1912 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1913 className: "mt-1 text-sm", 1914 children: valueAt ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1915 className: "flex items-start gap-3", 1916 children: [ 1917 valueIcon ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1918 className: "inline-flex h-8 w-8 items-center justify-center rounded border border-border bg-card", 1919 children: (0, __TURBOPACK__imported__module__158715__["renderDictionaryIcon"])(valueIcon, "h-4 w-4") 1920 }) : null,
1921 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1922 className: "flex-1", 1923 children: [ 1924 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1925 className: "block", 1926 children: (0, __TURBOPACK__imported__module__207623__["formatDateTime"])(valueAt) 1927 }), 1928 valueName ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1929 className: "text-xs text-muted-foreground", 1930 children: valueName 1931 }) : null, 1932 valueRefId ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("span", { 1933 className: "text-xs text-muted-foreground", 1934 children: [ 1935 "#", 1936 valueRefId 1937 ] 1938 }) : null 1939 ] 1940 }), 1941 valueColor ? (0, __TURBOPACK__imported__module__158715__["renderDictionaryColor"])(valueColor, "h-3 w-3 rounded-full border border-border") : null 1942 ] 1943 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1944 className: "text-muted-foreground", 1945 children: emptyLabel 1946 }) 1947 }) 1948 ] 1949 }) 1950 }) 1951 ] 1952 }); 1953} 1954; 1955__turbopack_context__.s([ 1956 "InlineDictionaryEditor", 1957 0, 1958 InlineDictionaryEditor, 1959 "InlineNextInteractionEditor", 1960 0, 1961 InlineNextInteractionEditor, 1962 "InlineTextEditor", 1963 0, 1964 InlineTextEditor, 1965 "renderLinkedInDisplay", 1966 0, 1967 renderLinkedInDisplay, 1968 "renderMultilineMarkdownDisplay", 1969 0, 1970 renderMultilineMarkdownDisplay, 1971 "renderTwitterDisplay", 1972 0, 1973 renderTwitterDisplay 1974]); 1975}), 1976609375, ((__turbopack_context__) => { 1977"use strict"; 1978 1979var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 1980var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 1981var __TURBOPACK__imported__module__110035__ = __turbopack_context__.i(110035); 1982var __TURBOPACK__imported__module__223922__ = __turbopack_context__.i(223922); 1983var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 1984var __TURBOPACK__imported__module__107233__ = __turbopack_context__.i(107233); 1985"use client"; 1986; 1987; 1988; 1989; 1990; 1991; 1992function DetailTabsLayout({ tabs, activeTab, onTabChange, sectionAction, onSectionAction, navAriaLabel, className, headerClassName, navClassName, children }) { 1993 const handleTabChange = __TURBOPACK__imported__module__271645__["useCallback"]((id)=>{ 1994 onTabChange(id); 1995 }, [ 1996 onTabChange 1997 ]); 1998 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1999 className: (0, __TURBOPACK__imported__module__406911__["cn"])("space-y-4", className), 2000 children: [
2001 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 2002 className: (0, __TURBOPACK__imported__module__406911__["cn"])("flex flex-wrap items-center justify-between gap-3", headerClassName), 2003 children: [ 2004 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__223922__["Tabs"], { 2005 value: activeTab, 2006 onValueChange: (value)=>handleTabChange(value), 2007 variant: "underline", 2008 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__223922__["TabsList"], { 2009 className: (0, __TURBOPACK__imported__module__406911__["cn"])("h-auto flex-wrap border-b-0", navClassName), 2010 "aria-label": navAriaLabel, 2011 children: tabs.map((tab)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__223922__["TabsTrigger"], { 2012 value: tab.id, 2013 children: tab.label 2014 }, tab.id)) 2015 }) 2016 }), 2017 sectionAction ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__110035__["Button"], { 2018 type: "button", 2019 size: "sm", 2020 onClick: onSectionAction, 2021 disabled: sectionAction.disabled, 2022 children: [ 2023 sectionAction.icon ?? (typeof sectionAction.label === "string" || typeof sectionAction.label === "number" ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 2024 className: "mr-2 h-4 w-4" 2025 }) : null), 2026 sectionAction.label 2027 ] 2028 }) : null 2029 ] 2030 }),
2031 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 2032 children 2033 }) 2034 ] 2035 }); 2036} 2037; 2038__turbopack_context__.s([ 2039 "DetailTabsLayout", 2040 0, 2041 DetailTabsLayout 2042]); 2043}), 2044]);
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.