@open-mercato/ui 0.7.0 → 0.7.1-develop.7103.1.41ff100d93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/ai/records/ActivityCard.js +4 -3
  3. package/dist/ai/records/ActivityCard.js.map +2 -2
  4. package/dist/ai/records/DealCard.js +4 -3
  5. package/dist/ai/records/DealCard.js.map +2 -2
  6. package/dist/ai/records/ProductCard.js +3 -2
  7. package/dist/ai/records/ProductCard.js.map +2 -2
  8. package/dist/backend/AppShell.js +129 -106
  9. package/dist/backend/AppShell.js.map +2 -2
  10. package/dist/backend/DataTable.js +20 -7
  11. package/dist/backend/DataTable.js.map +2 -2
  12. package/dist/backend/detail/NotesSection.js +26 -20
  13. package/dist/backend/detail/NotesSection.js.map +2 -2
  14. package/dist/backend/icons/lucideRegistry.generated.js +4 -0
  15. package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
  16. package/dist/backend/injection/useRegisteredComponent.js +24 -6
  17. package/dist/backend/injection/useRegisteredComponent.js.map +2 -2
  18. package/dist/backend/inputs/ComboboxInput.js +8 -4
  19. package/dist/backend/inputs/ComboboxInput.js.map +2 -2
  20. package/dist/backend/inputs/LookupSelect.js +8 -8
  21. package/dist/backend/inputs/LookupSelect.js.map +2 -2
  22. package/dist/backend/sidebar/SidebarCustomizationEditor.js +36 -30
  23. package/dist/backend/sidebar/SidebarCustomizationEditor.js.map +2 -2
  24. package/dist/backend/utils/crud.js.map +2 -2
  25. package/dist/primitives/alert.js +1 -1
  26. package/dist/primitives/alert.js.map +2 -2
  27. package/dist/primitives/icon-button.js +20 -1
  28. package/dist/primitives/icon-button.js.map +2 -2
  29. package/dist/primitives/pagination.js +14 -9
  30. package/dist/primitives/pagination.js.map +2 -2
  31. package/dist/primitives/rich-editor.js +14 -7
  32. package/dist/primitives/rich-editor.js.map +2 -2
  33. package/dist/utils/format.js +5 -5
  34. package/dist/utils/format.js.map +2 -2
  35. package/package.json +5 -4
  36. package/src/ai/parts/__tests__/ConfirmationCard.test.tsx +2 -0
  37. package/src/ai/records/ActivityCard.tsx +4 -3
  38. package/src/ai/records/DealCard.tsx +4 -3
  39. package/src/ai/records/ProductCard.tsx +3 -2
  40. package/src/backend/AppShell.tsx +89 -58
  41. package/src/backend/DataTable.tsx +44 -10
  42. package/src/backend/__tests__/AppShell.test.tsx +162 -1
  43. package/src/backend/__tests__/DataTable.cappedPagination.test.tsx +122 -0
  44. package/src/backend/__tests__/DataTable.headerWrap.test.tsx +111 -0
  45. package/src/backend/__tests__/DataTable.render.test.tsx +37 -0
  46. package/src/backend/__tests__/NotesSection.test.tsx +89 -0
  47. package/src/backend/__tests__/useRegisteredComponent.identity.test.tsx +305 -0
  48. package/src/backend/detail/NotesSection.tsx +92 -67
  49. package/src/backend/icons/lucideRegistry.generated.tsx +4 -0
  50. package/src/backend/injection/useRegisteredComponent.tsx +49 -8
  51. package/src/backend/inputs/ComboboxInput.tsx +21 -5
  52. package/src/backend/inputs/LookupSelect.tsx +8 -8
  53. package/src/backend/inputs/__tests__/ComboboxInput.test.tsx +142 -0
  54. package/src/backend/inputs/__tests__/LookupSelect.test.tsx +75 -0
  55. package/src/backend/sidebar/SidebarCustomizationEditor.tsx +14 -11
  56. package/src/backend/utils/crud.ts +2 -0
  57. package/src/primitives/__tests__/alert.test.tsx +41 -1
  58. package/src/primitives/__tests__/icon-button.test.tsx +70 -0
  59. package/src/primitives/__tests__/notification.test.tsx +1 -1
  60. package/src/primitives/__tests__/pagination.test.tsx +54 -0
  61. package/src/primitives/__tests__/rich-editor.test.tsx +43 -0
  62. package/src/primitives/alert.tsx +5 -2
  63. package/src/primitives/icon-button.tsx +20 -1
  64. package/src/primitives/pagination.tsx +40 -9
  65. package/src/primitives/rich-editor.tsx +9 -4
  66. package/src/utils/__tests__/format.test.ts +27 -14
  67. package/src/utils/format.ts +10 -5
@@ -134,7 +134,10 @@ function NotesSectionImpl({
134
134
  iconSuggestions,
135
135
  readMarkdownPreference,
136
136
  writeMarkdownPreference,
137
- disableMarkdown
137
+ disableMarkdown,
138
+ forceMarkdown,
139
+ hideMarkdownToggle,
140
+ disableAppearance
138
141
  }) {
139
142
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
140
143
  const t = React.useMemo(() => translator ?? ((key, fallback) => fallback ?? key), [translator]);
@@ -246,13 +249,16 @@ function NotesSectionImpl({
246
249
  const [draftIcon, setDraftIcon] = React.useState(null);
247
250
  const [draftColor, setDraftColor] = React.useState(null);
248
251
  const [isMarkdownEnabled, setIsMarkdownEnabled] = React.useState(false);
252
+ const isMarkdownActive = !disableMarkdown && (Boolean(forceMarkdown) || isMarkdownEnabled);
253
+ const showMarkdownToggle = !disableMarkdown && !forceMarkdown && !hideMarkdownToggle;
254
+ const showAppearanceControls = !disableAppearance;
249
255
  const textareaRef = React.useRef(null);
250
256
  const formRef = React.useRef(null);
251
257
  const focusComposer = React.useCallback(() => {
252
258
  if (!hasEntity) return;
253
259
  setComposerOpen(true);
254
260
  window.requestAnimationFrame(() => {
255
- if (isMarkdownEnabled) {
261
+ if (isMarkdownActive) {
256
262
  const markdownTextarea = formRef.current?.querySelector("textarea");
257
263
  if (markdownTextarea instanceof HTMLTextAreaElement) {
258
264
  markdownTextarea.focus();
@@ -265,7 +271,7 @@ function NotesSectionImpl({
265
271
  element.focus();
266
272
  element.scrollIntoView({ behavior: "smooth", block: "center" });
267
273
  });
268
- }, [formRef, hasEntity, isMarkdownEnabled]);
274
+ }, [formRef, hasEntity, isMarkdownActive]);
269
275
  const [appearanceDialogState, setAppearanceDialogState] = React.useState(null);
270
276
  const [appearanceDialogSaving, setAppearanceDialogSaving] = React.useState(false);
271
277
  const [appearanceDialogError, setAppearanceDialogError] = React.useState(null);
@@ -369,7 +375,7 @@ function NotesSectionImpl({
369
375
  }, []);
370
376
  React.useEffect(() => {
371
377
  adjustTextareaSize(textareaRef.current);
372
- }, [adjustTextareaSize, draftBody, isMarkdownEnabled, composerOpen]);
378
+ }, [adjustTextareaSize, draftBody, isMarkdownActive, composerOpen]);
373
379
  React.useEffect(() => {
374
380
  const preference = readMarkdownPreference ? readMarkdownPreference() : null;
375
381
  if (preference !== null) {
@@ -731,7 +737,7 @@ function NotesSectionImpl({
731
737
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
732
738
  /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: label("addLabel") }),
733
739
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
734
- /* @__PURE__ */ jsxs(
740
+ showAppearanceControls ? /* @__PURE__ */ jsxs(
735
741
  Button,
736
742
  {
737
743
  type: "button",
@@ -747,19 +753,19 @@ function NotesSectionImpl({
747
753
  /* @__PURE__ */ jsx(Palette, { className: "h-4 w-4" })
748
754
  ]
749
755
  }
750
- ),
751
- disableMarkdown ? null : /* @__PURE__ */ jsx(
756
+ ) : null,
757
+ showMarkdownToggle ? /* @__PURE__ */ jsx(
752
758
  Button,
753
759
  {
754
760
  type: "button",
755
- variant: isMarkdownEnabled ? "secondary" : "ghost",
761
+ variant: isMarkdownActive ? "secondary" : "ghost",
756
762
  size: "icon",
757
763
  onClick: handleMarkdownToggle,
758
- "aria-pressed": isMarkdownEnabled,
764
+ "aria-pressed": isMarkdownActive,
759
765
  disabled: isSubmitting || isLoading,
760
766
  children: /* @__PURE__ */ jsx(FileCode, { className: "h-4 w-4" })
761
767
  }
762
- ),
768
+ ) : null,
763
769
  /* @__PURE__ */ jsx(
764
770
  Button,
765
771
  {
@@ -829,7 +835,7 @@ function NotesSectionImpl({
829
835
  {
830
836
  value: draftBody,
831
837
  onChange: setDraftBody,
832
- isMarkdownEnabled,
838
+ isMarkdownEnabled: isMarkdownActive,
833
839
  disableMarkdown,
834
840
  rows: 1,
835
841
  placeholder: label("placeholder"),
@@ -952,7 +958,7 @@ function NotesSectionImpl({
952
958
  children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
953
959
  }
954
960
  ),
955
- /* @__PURE__ */ jsx(
961
+ showAppearanceControls ? /* @__PURE__ */ jsx(
956
962
  Button,
957
963
  {
958
964
  type: "button",
@@ -971,7 +977,7 @@ function NotesSectionImpl({
971
977
  disabled: appearanceDialogSaving && editingAppearanceNoteId === note.id,
972
978
  children: isAppearanceSaving ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Palette, { className: "h-4 w-4" })
973
979
  }
974
- ),
980
+ ) : null,
975
981
  /* @__PURE__ */ jsx(
976
982
  Button,
977
983
  {
@@ -996,7 +1002,7 @@ function NotesSectionImpl({
996
1002
  {
997
1003
  value: contentEditor.value,
998
1004
  onChange: (nextValue) => setContentEditor((prev) => ({ ...prev, value: nextValue })),
999
- isMarkdownEnabled,
1005
+ isMarkdownEnabled: isMarkdownActive,
1000
1006
  disableMarkdown,
1001
1007
  rows: 3,
1002
1008
  textareaRef: contentTextareaRef,
@@ -1012,19 +1018,19 @@ function NotesSectionImpl({
1012
1018
  /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1013
1019
  label("saving")
1014
1020
  ] }) : inlineLabel("saveShortcut") }),
1015
- disableMarkdown ? null : /* @__PURE__ */ jsx(
1021
+ showMarkdownToggle ? /* @__PURE__ */ jsx(
1016
1022
  Button,
1017
1023
  {
1018
1024
  type: "button",
1019
1025
  variant: "ghost",
1020
1026
  size: "icon",
1021
1027
  onClick: handleMarkdownToggle,
1022
- "aria-pressed": isMarkdownEnabled,
1023
- className: isMarkdownEnabled ? "text-primary" : void 0,
1028
+ "aria-pressed": isMarkdownActive,
1029
+ className: isMarkdownActive ? "text-primary" : void 0,
1024
1030
  disabled: contentSavingId === note.id,
1025
1031
  children: /* @__PURE__ */ jsx(FileCode, { className: "h-4 w-4" })
1026
1032
  }
1027
- ),
1033
+ ) : null,
1028
1034
  /* @__PURE__ */ jsx(
1029
1035
  Button,
1030
1036
  {
@@ -1070,7 +1076,7 @@ function NotesSectionImpl({
1070
1076
  ),
1071
1077
  isLoading || (pagedMode ? !hasMore : visibleCount >= notes.length) ? null : /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleLoadMore, children: loadMoreLabel }) })
1072
1078
  ] }),
1073
- /* @__PURE__ */ jsx(
1079
+ showAppearanceControls ? /* @__PURE__ */ jsx(
1074
1080
  AppearanceDialog,
1075
1081
  {
1076
1082
  open: appearanceDialogOpen,
@@ -1091,7 +1097,7 @@ function NotesSectionImpl({
1091
1097
  savingLabel: appearanceDialogSavingLabel,
1092
1098
  cancelLabel: label("appearance.cancel")
1093
1099
  }
1094
- ),
1100
+ ) : null,
1095
1101
  ConfirmDialogElement
1096
1102
  ] });
1097
1103
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/detail/NotesSection.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { PluggableList } from 'unified'\nimport type { AppearanceSelectorLabels } from '@open-mercato/core/modules/dictionaries/components/AppearanceSelector'\nimport { AppearanceDialog } from '@open-mercato/core/modules/customers/components/detail/AppearanceDialog'\nimport type { IconOption } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ArrowUpRightSquare, FileCode, Loader2, Palette, Pencil, Plus, Trash2 } from 'lucide-react'\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\nimport { hasMoreFromPage } from '@open-mercato/shared/lib/pagination/load-more'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { flash } from '../FlashMessages'\nimport { surfaceRecordConflict } from '../conflicts'\nimport { SwitchableMarkdownInput } from '../inputs/SwitchableMarkdownInput'\nimport { ErrorMessage } from './ErrorMessage'\nimport { LoadingMessage } from './LoadingMessage'\nimport { TabEmptyState } from './TabEmptyState'\nimport { useConfirmDialog } from '../confirm-dialog'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\nimport { ComponentReplacementHandles } from '@open-mercato/shared/modules/widgets/component-registry'\nimport { MarkdownPreview } from '../markdown'\nimport { useRegisteredComponent } from '../injection/useRegisteredComponent'\ntype Translator = (key: string, fallback?: string, params?: Record<string, string | number>) => string\n\nconst NOTES_PAGE_SIZE = 20\n\nconst isTestEnv =\n typeof process !== 'undefined' &&\n (process.env.NODE_ENV === 'test' || typeof process.env.JEST_WORKER_ID !== 'undefined')\n\nexport type SectionAction = {\n label: React.ReactNode\n onClick: () => void\n disabled?: boolean\n icon?: React.ReactNode\n}\n\nexport type TabEmptyStateConfig = {\n title: string\n actionLabel: string\n description?: string\n}\n\nexport type CommentSummary = {\n id: string\n body: string\n createdAt: string\n updatedAt?: string | null\n authorUserId?: string | null\n authorName?: string | null\n authorEmail?: string | null\n dealId?: string | null\n dealTitle?: string | null\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesCreatePayload = {\n entityId: string\n body: string\n appearanceIcon: string | null\n appearanceColor: string | null\n dealId?: string | null\n}\n\nexport type NotesUpdatePayload = {\n body?: string\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesDataAdapter<C = unknown> = {\n list: (params: { entityId: string | null; dealId: string | null; context?: C }) => Promise<CommentSummary[]>\n listPage?: (params: {\n entityId: string | null\n dealId: string | null\n page: number\n pageSize: number\n context?: C\n }) => Promise<{\n items: CommentSummary[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n }>\n create: (params: NotesCreatePayload & { context?: C }) => Promise<Partial<CommentSummary> | void>\n update: (params: { id: string; patch: NotesUpdatePayload; updatedAt?: string | null; context?: C }) => Promise<void>\n delete: (params: { id: string; updatedAt?: string | null; context?: C }) => Promise<void>\n}\n\ntype RenderIconFn = (icon: string, className?: string) => React.ReactNode\ntype RenderColorFn = (color: string, className?: string) => React.ReactNode\n\nlet markdownPluginsPromise: Promise<PluggableList> | null = null\n\nasync function loadMarkdownPlugins(): Promise<PluggableList> {\n if (isTestEnv) return []\n if (!markdownPluginsPromise) {\n markdownPluginsPromise = import('remark-gfm')\n .then((mod) => [mod.default ?? mod] as PluggableList)\n .catch(() => [])\n }\n return markdownPluginsPromise\n}\n\nfunction generateTempId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') return crypto.randomUUID()\n return `tmp_${Math.random().toString(36).slice(2)}`\n}\n\n\n\ntype TimelineItemHeaderProps = {\n title: React.ReactNode\n subtitle?: React.ReactNode\n timestamp?: string | Date | null\n fallbackTimestampLabel?: React.ReactNode\n icon?: string | null\n color?: string | null\n iconSize?: 'sm' | 'md'\n className?: string\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n}\n\nfunction TimelineItemHeader({\n title,\n subtitle,\n timestamp,\n fallbackTimestampLabel,\n icon,\n color,\n iconSize = 'md',\n className,\n renderIcon,\n renderColor,\n}: TimelineItemHeaderProps) {\n const wrapperSize = iconSize === 'sm' ? 'h-6 w-6' : 'h-8 w-8'\n const iconSizeClass = iconSize === 'sm' ? 'h-3.5 w-3.5' : 'h-4 w-4'\n const resolvedTimestamp = React.useMemo(() => {\n if (subtitle) return subtitle\n if (!timestamp) return fallbackTimestampLabel ?? null\n const value = typeof timestamp === 'string' ? timestamp : timestamp.toISOString()\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallbackTimestampLabel ?? null\n const now = Date.now()\n const diff = Math.abs(now - date.getTime())\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000\n const relativeLabel = diff <= THIRTY_DAYS_MS ? formatRelativeTime(value) : null\n const absoluteLabel = formatDateTime(value)\n if (relativeLabel) {\n return (\n <span title={absoluteLabel ?? undefined}>\n {relativeLabel}\n </span>\n )\n }\n return absoluteLabel ?? fallbackTimestampLabel ?? null\n }, [fallbackTimestampLabel, subtitle, timestamp])\n\n return (\n <div className={['flex items-start gap-3', className].filter(Boolean).join(' ')}>\n {icon && renderIcon ? (\n <span className={['inline-flex items-center justify-center rounded border border-border bg-muted/50', wrapperSize].join(' ')}>\n {renderIcon(icon, iconSizeClass)}\n </span>\n ) : null}\n <div className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">{title}</span>\n {color && renderColor ? renderColor(color, 'h-3 w-3 rounded-full border border-border') : null}\n </div>\n {resolvedTimestamp ? <div className=\"text-xs text-muted-foreground\">{resolvedTimestamp}</div> : null}\n </div>\n </div>\n )\n}\n\nexport type NotesSectionProps<C = unknown> = {\n entityId: string | null\n dealId?: string | null\n emptyLabel: string\n viewerUserId: string | null\n viewerName?: string | null\n viewerEmail?: string | null\n addActionLabel: string\n emptyState: TabEmptyStateConfig\n onActionChange?: (action: SectionAction | null) => void\n translator?: Translator\n labelPrefix?: string\n inlineLabelPrefix?: string\n onLoadingChange?: (isLoading: boolean) => void\n dealOptions?: Array<{ id: string; label: string }>\n entityOptions?: Array<{ id: string; label: string }>\n dataAdapter: NotesDataAdapter<C>\n dataContext?: C\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n iconSuggestions?: IconOption[]\n readMarkdownPreference?: () => boolean | null\n writeMarkdownPreference?: (value: boolean) => void\n disableMarkdown?: boolean\n}\n\nexport function sanitizeHexColor(value: string | null): string | null {\n if (!value) return null\n const trimmed = value.trim()\n return /^#([0-9a-f]{6})$/i.test(trimmed) ? trimmed.toLowerCase() : null\n}\n\nexport function mapCommentSummary(input: unknown): CommentSummary {\n const data = (typeof input === 'object' && input !== null ? input : {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : generateTempId()\n const body = typeof data.body === 'string' ? data.body : ''\n const createdAt =\n typeof data.createdAt === 'string'\n ? data.createdAt\n : typeof data.created_at === 'string'\n ? data.created_at\n : new Date().toISOString()\n const updatedAt =\n typeof data.updatedAt === 'string'\n ? data.updatedAt\n : typeof data.updated_at === 'string'\n ? data.updated_at\n : null\n const authorUserId =\n typeof data.authorUserId === 'string'\n ? data.authorUserId\n : typeof data.author_user_id === 'string'\n ? data.author_user_id\n : null\n const authorName =\n typeof data.authorName === 'string'\n ? data.authorName\n : typeof data.author_name === 'string'\n ? data.author_name\n : null\n const authorEmail =\n typeof data.authorEmail === 'string'\n ? data.authorEmail\n : typeof data.author_email === 'string'\n ? data.author_email\n : null\n const dealId =\n typeof data.dealId === 'string'\n ? data.dealId\n : typeof data.deal_id === 'string'\n ? data.deal_id\n : null\n const dealTitle =\n typeof data.dealTitle === 'string'\n ? data.dealTitle\n : typeof data.deal_title === 'string'\n ? data.deal_title\n : null\n const appearanceIcon =\n typeof data.appearanceIcon === 'string'\n ? data.appearanceIcon\n : typeof data.appearance_icon === 'string'\n ? data.appearance_icon\n : null\n const appearanceColor =\n typeof data.appearanceColor === 'string'\n ? data.appearanceColor\n : typeof data.appearance_color === 'string'\n ? data.appearance_color\n : null\n return {\n id,\n body,\n createdAt,\n updatedAt,\n authorUserId,\n authorName,\n authorEmail,\n dealId,\n dealTitle,\n appearanceIcon,\n appearanceColor,\n }\n}\n\nfunction NotesSectionImpl<C = unknown>({\n entityId,\n dealId,\n emptyLabel,\n viewerUserId,\n viewerName,\n viewerEmail,\n addActionLabel,\n emptyState,\n onActionChange,\n translator,\n labelPrefix = 'customers.people.detail.notes',\n inlineLabelPrefix = 'customers.people.detail.inline',\n onLoadingChange,\n dealOptions,\n entityOptions,\n dataAdapter,\n dataContext,\n renderIcon,\n renderColor,\n iconSuggestions,\n readMarkdownPreference,\n writeMarkdownPreference,\n disableMarkdown,\n}: NotesSectionProps<C>) {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const t = React.useMemo<Translator>(() => translator ?? ((key, fallback) => fallback ?? key), [translator])\n const label = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${labelPrefix}.${suffix}`, fallback, params),\n [labelPrefix, t],\n )\n const inlineLabel = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${inlineLabelPrefix}.${suffix}`, fallback, params),\n [inlineLabelPrefix, t],\n )\n const [markdownPlugins, setMarkdownPlugins] = React.useState<PluggableList>([])\n React.useEffect(() => {\n if (isTestEnv) return\n let mounted = true\n void loadMarkdownPlugins().then((plugins) => {\n if (!mounted) return\n setMarkdownPlugins(plugins)\n })\n return () => {\n mounted = false\n }\n }, [])\n\n const normalizedDealOptions = React.useMemo(() => {\n if (!Array.isArray(dealOptions)) return []\n const seen = new Set<string>()\n return dealOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [dealOptions])\n\n const dealLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n normalizedDealOptions.forEach((option) => {\n map.set(option.id, option.label)\n })\n return map\n }, [normalizedDealOptions])\n\n const normalizedEntityOptions = React.useMemo(() => {\n if (!Array.isArray(entityOptions)) return []\n const seen = new Set<string>()\n return entityOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [entityOptions])\n\n const [selectedDealId, setSelectedDealId] = React.useState<string>(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n return initial\n })\n React.useEffect(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n if (initial !== selectedDealId) {\n setSelectedDealId(initial)\n }\n }, [dealId, selectedDealId])\n\n const [selectedEntityId, setSelectedEntityId] = React.useState<string>(() => {\n if (normalizedEntityOptions.length) return normalizedEntityOptions[0].id\n return typeof entityId === 'string' ? entityId : ''\n })\n React.useEffect(() => {\n if (normalizedEntityOptions.length) {\n if (!normalizedEntityOptions.some((option) => option.id === selectedEntityId)) {\n setSelectedEntityId(normalizedEntityOptions[0].id)\n }\n } else {\n const initial = typeof entityId === 'string' ? entityId : ''\n if (initial !== selectedEntityId) {\n setSelectedEntityId(initial)\n }\n }\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedEntityId = React.useMemo(() => {\n if (normalizedEntityOptions.length) return selectedEntityId\n return typeof entityId === 'string' ? entityId : ''\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedDealId = React.useMemo(() => {\n const trimmed = typeof selectedDealId === 'string' ? selectedDealId.trim() : ''\n return trimmed\n }, [selectedDealId])\n\n const hasEntity = resolvedEntityId.length > 0\n\n const [notes, setNotes] = React.useState<CommentSummary[]>([])\n const [isLoading, setIsLoading] = React.useState<boolean>(() => Boolean(entityId || dealId))\n const [isSubmitting, setIsSubmitting] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const pendingCounterRef = React.useRef(0)\n\n const pushLoading = React.useCallback(() => {\n pendingCounterRef.current += 1\n if (pendingCounterRef.current === 1) {\n onLoadingChange?.(true)\n }\n }, [onLoadingChange])\n\n const popLoading = React.useCallback(() => {\n pendingCounterRef.current = Math.max(0, pendingCounterRef.current - 1)\n if (pendingCounterRef.current === 0) {\n onLoadingChange?.(false)\n }\n }, [onLoadingChange])\n\n const [composerOpen, setComposerOpen] = React.useState(false)\n const [draftBody, setDraftBody] = React.useState('')\n const [draftIcon, setDraftIcon] = React.useState<string | null>(null)\n const [draftColor, setDraftColor] = React.useState<string | null>(null)\n const [isMarkdownEnabled, setIsMarkdownEnabled] = React.useState(false)\n const textareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const formRef = React.useRef<HTMLFormElement | null>(null)\n const focusComposer = React.useCallback(() => {\n if (!hasEntity) return\n setComposerOpen(true)\n window.requestAnimationFrame(() => {\n if (isMarkdownEnabled) {\n const markdownTextarea = formRef.current?.querySelector('textarea')\n if (markdownTextarea instanceof HTMLTextAreaElement) {\n markdownTextarea.focus()\n markdownTextarea.scrollIntoView({ behavior: 'smooth', block: 'center' })\n return\n }\n }\n const element = textareaRef.current\n if (!element) return\n element.focus()\n element.scrollIntoView({ behavior: 'smooth', block: 'center' })\n })\n }, [formRef, hasEntity, isMarkdownEnabled])\n const [appearanceDialogState, setAppearanceDialogState] = React.useState<\n | { mode: 'create'; icon: string | null; color: string | null }\n | { mode: 'edit'; noteId: string; icon: string | null; color: string | null }\n | null\n >(null)\n const [appearanceDialogSaving, setAppearanceDialogSaving] = React.useState(false)\n const [appearanceDialogError, setAppearanceDialogError] = React.useState<string | null>(null)\n const [contentEditor, setContentEditor] = React.useState<{ id: string; value: string }>({ id: '', value: '' })\n const [contentSavingId, setContentSavingId] = React.useState<string | null>(null)\n const [contentError, setContentError] = React.useState<string | null>(null)\n const contentTextareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const [visibleCount, setVisibleCount] = React.useState(0)\n const [currentPage, setCurrentPage] = React.useState(1)\n // Short-page termination instead of `currentPage >= totalPages` \u2014 see\n // `hasMoreFromPage`. `/api/customers/comments` is a `makeCrudRoute` list, so\n // a page past the end comes back empty rather than clamped.\n const [hasMore, setHasMore] = React.useState(false)\n const [deletingNoteId, setDeletingNoteId] = React.useState<string | null>(null)\n const pagedMode = typeof dataAdapter.listPage === 'function'\n\n React.useEffect(() => {\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n if (!queryEntityId && !queryDealId) {\n setNotes([])\n setLoadError(null)\n setIsLoading(false)\n setCurrentPage(1)\n setHasMore(false)\n return\n }\n let cancelled = false\n setIsLoading(true)\n setLoadError(null)\n pushLoading()\n async function loadNotes() {\n try {\n if (dataAdapter.listPage) {\n const pageResult = await dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(pageResult.items)\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n return\n }\n const mapped = await dataAdapter.list({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(mapped)\n setCurrentPage(1)\n setHasMore(false)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error ? err.message : label('loadError', 'Failed to load notes.')\n setNotes([])\n setLoadError(message)\n setCurrentPage(1)\n setHasMore(false)\n flash(message, 'error')\n } finally {\n if (!cancelled) setIsLoading(false)\n popLoading()\n }\n }\n loadNotes().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [dataAdapter, dataContext, dealId, entityId, label, popLoading, pushLoading])\n\n const youLabel = label('you', 'You')\n const viewerLabel = React.useMemo(() => viewerName ?? viewerEmail ?? null, [viewerEmail, viewerName])\n\n const handleMarkdownToggle = React.useCallback(() => {\n setIsMarkdownEnabled((prev) => {\n const next = !prev\n if (writeMarkdownPreference) {\n writeMarkdownPreference(next)\n }\n return next\n })\n }, [writeMarkdownPreference])\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (!notes.length) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || isLoading || !hasEntity,\n icon: <Plus className=\"mr-2 h-4 w-4\" />,\n })\n return () => onActionChange(null)\n }, [onActionChange, addActionLabel, focusComposer, hasEntity, isLoading, isSubmitting, notes.length])\n\n const adjustTextareaSize = React.useCallback((element: HTMLTextAreaElement | null) => {\n if (!element) return\n element.style.height = 'auto'\n element.style.height = `${element.scrollHeight}px`\n }, [])\n\n React.useEffect(() => {\n adjustTextareaSize(textareaRef.current)\n }, [adjustTextareaSize, draftBody, isMarkdownEnabled, composerOpen])\n\n React.useEffect(() => {\n const preference = readMarkdownPreference ? readMarkdownPreference() : null\n if (preference !== null) {\n setIsMarkdownEnabled(preference)\n }\n }, [readMarkdownPreference])\n\n React.useEffect(() => {\n if (pagedMode) {\n setVisibleCount(notes.length)\n return\n }\n if (!notes.length) {\n setVisibleCount(0)\n return\n }\n const baseline = Math.min(5, notes.length)\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(Math.max(prev, baseline), notes.length)\n })\n }, [notes.length, pagedMode])\n\n React.useEffect(() => {\n if (hasEntity) return\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }, [hasEntity])\n\n const visibleNotes = React.useMemo(\n () => (pagedMode ? notes : notes.slice(0, visibleCount)),\n [notes, pagedMode, visibleCount],\n )\n const hasVisibleNotes = React.useMemo(\n () => (pagedMode ? notes.length > 0 : visibleCount > 0),\n [notes.length, pagedMode, visibleCount],\n )\n\n const loadMoreLabel = label('loadMore')\n\n const handleCreateNote = React.useCallback(\n async (input: { body: string; appearanceIcon: string | null; appearanceColor: string | null }) => {\n if (!hasEntity || !resolvedEntityId) {\n flash(label('entityMissing', 'Unable to determine current person.'), 'error')\n return false\n }\n const body = input.body.trim()\n const strippedBody = body\n .replace(/^[\\s#\\-*>_~`|+\\\\\\n\\r]+$/gm, '')\n .replace(/\\s+/g, '')\n if (!body || !strippedBody.length) {\n focusComposer()\n return false\n }\n const icon = input.appearanceIcon && input.appearanceIcon.trim().length ? input.appearanceIcon.trim() : null\n const color = sanitizeHexColor(input.appearanceColor)\n const targetDealId = resolvedDealId.length ? resolvedDealId : null\n const dealLabel = targetDealId ? dealLabelMap.get(targetDealId) ?? null : null\n setIsSubmitting(true)\n pushLoading()\n try {\n const responseBody =\n (await dataAdapter.create({\n entityId: resolvedEntityId,\n body,\n appearanceIcon: icon,\n appearanceColor: color,\n dealId: targetDealId,\n context: dataContext,\n })) ?? {}\n setNotes((prev) => {\n const viewerId = viewerUserId ?? null\n const resolvedAuthorId =\n typeof responseBody?.authorUserId === 'string' ? responseBody.authorUserId : viewerId ?? null\n const resolvedAuthorName = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return youLabel\n }\n return typeof responseBody?.authorName === 'string' ? responseBody.authorName : viewerLabel\n })()\n const resolvedAuthorEmail = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return viewerEmail ?? null\n }\n return typeof responseBody?.authorEmail === 'string' ? responseBody.authorEmail : null\n })()\n const newNote: CommentSummary = {\n id: typeof responseBody?.id === 'string' ? responseBody.id : generateTempId(),\n body,\n createdAt: new Date().toISOString(),\n authorUserId: resolvedAuthorId,\n authorName: resolvedAuthorName,\n authorEmail: resolvedAuthorEmail,\n dealId: targetDealId,\n dealTitle: dealLabel,\n appearanceIcon: icon,\n appearanceColor: color,\n }\n return [newNote, ...prev]\n })\n setVisibleCount((prev) => Math.max(prev, 1))\n flash(label('success'), 'success')\n return true\n } catch (err) {\n const message = err instanceof Error ? err.message : label('error')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n return false\n } finally {\n setIsSubmitting(false)\n popLoading()\n }\n },\n [dataAdapter, dataContext, dealLabelMap, focusComposer, hasEntity, popLoading, pushLoading, resolvedDealId, resolvedEntityId, t, viewerEmail, viewerLabel, viewerUserId, youLabel],\n )\n\n const handleUpdateNote = React.useCallback(\n async (noteId: string, patch: { body?: string; appearanceIcon?: string | null; appearanceColor?: string | null }) => {\n const sanitizedBody = patch.body\n const sanitizedIcon =\n patch.appearanceIcon !== undefined && patch.appearanceIcon !== null && patch.appearanceIcon.trim().length\n ? patch.appearanceIcon.trim()\n : patch.appearanceIcon === null\n ? null\n : undefined\n const sanitizedColor =\n patch.appearanceColor !== undefined ? sanitizeHexColor(patch.appearanceColor ?? null) : undefined\n const noteUpdatedAt = notes.find((comment) => comment.id === noteId)?.updatedAt ?? null\n try {\n await dataAdapter.update({\n id: noteId,\n patch: {\n body: sanitizedBody,\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n },\n updatedAt: noteUpdatedAt,\n context: dataContext,\n })\n setNotes((prev) => {\n const nextComments = prev.map((comment) => {\n if (comment.id !== noteId) return comment\n const next = { ...comment }\n if (sanitizedBody !== undefined) next.body = sanitizedBody\n if (sanitizedIcon !== undefined) next.appearanceIcon = sanitizedIcon ?? null\n if (sanitizedColor !== undefined) next.appearanceColor = sanitizedColor ?? null\n return next\n })\n return nextComments\n })\n flash(label('updateSuccess'), 'success')\n } catch (error) {\n const message = error instanceof Error ? error.message : label('updateError')\n if (!surfaceRecordConflict(error, t)) flash(message, 'error')\n throw error instanceof Error ? error : new Error(message)\n }\n },\n [dataAdapter, dataContext, notes, t],\n )\n\n const handleDeleteNote = React.useCallback(\n async (note: CommentSummary) => {\n const confirmed = await confirm({\n title: label('deleteConfirm', 'Delete this note? You can restore it using version history.'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setDeletingNoteId(note.id)\n pushLoading()\n try {\n await dataAdapter.delete({ id: note.id, updatedAt: note.updatedAt ?? null, context: dataContext })\n setNotes((prev) => prev.filter((existing) => existing.id !== note.id))\n if (pagedMode) {\n setVisibleCount((prev) => Math.max(0, prev - 1))\n }\n flash(label('deleteSuccess', 'Note deleted'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : label('deleteError', 'Failed to delete note')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n } finally {\n setDeletingNoteId(null)\n popLoading()\n }\n },\n [confirm, dataAdapter, dataContext, label, popLoading, pushLoading, t],\n )\n\n const handleSubmit = React.useCallback(\n async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const created = await handleCreateNote({\n body: draftBody,\n appearanceIcon: draftIcon,\n appearanceColor: draftColor,\n })\n if (created) {\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }\n },\n [draftBody, draftColor, draftIcon, handleCreateNote],\n )\n\n const handleLoadMore = React.useCallback(() => {\n if (pagedMode && dataAdapter.listPage) {\n if (!hasMore || isLoading) return\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n setIsLoading(true)\n pushLoading()\n void dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: currentPage + 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n .then((pageResult) => {\n setNotes((prev) => {\n const merged = new Map(prev.map((note) => [note.id, note]))\n pageResult.items.forEach((note) => merged.set(note.id, note))\n return Array.from(merged.values())\n })\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n })\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : label('loadError', 'Failed to load notes.')\n flash(message, 'error')\n })\n .finally(() => {\n setIsLoading(false)\n popLoading()\n })\n return\n }\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(prev + 5, notes.length)\n })\n }, [currentPage, dataAdapter, dataContext, dealId, entityId, flash, hasMore, isLoading, label, notes.length, pagedMode, popLoading, pushLoading])\n\n const handleAppearanceDialogSubmit = React.useCallback(async () => {\n if (!appearanceDialogState) return\n setAppearanceDialogError(null)\n const sanitizedIcon =\n appearanceDialogState.icon && appearanceDialogState.icon.trim().length\n ? appearanceDialogState.icon.trim()\n : null\n const sanitizedColor = sanitizeHexColor(appearanceDialogState.color ?? null)\n if (appearanceDialogState.mode === 'create') {\n setDraftIcon(sanitizedIcon)\n setDraftColor(sanitizedColor)\n setAppearanceDialogState(null)\n return\n }\n setAppearanceDialogSaving(true)\n try {\n await handleUpdateNote(appearanceDialogState.noteId, {\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n })\n setAppearanceDialogState(null)\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : label('appearance.error', 'Failed to update appearance.')\n setAppearanceDialogError(message)\n } finally {\n setAppearanceDialogSaving(false)\n }\n }, [appearanceDialogState, handleUpdateNote, t])\n\n const handleAppearanceDialogClose = React.useCallback(() => {\n if (appearanceDialogSaving) return\n setAppearanceDialogState(null)\n setAppearanceDialogError(null)\n }, [appearanceDialogSaving])\n\n const handleContentSave = React.useCallback(async () => {\n if (!contentEditor.id) return\n const trimmed = contentEditor.value.trim()\n if (!trimmed) {\n setContentError(label('updateError', 'Failed to update note'))\n return\n }\n setContentSavingId(contentEditor.id)\n setContentError(null)\n try {\n await handleUpdateNote(contentEditor.id, { body: trimmed })\n setContentEditor({ id: '', value: '' })\n } catch (err) {\n const message =\n err instanceof Error ? err.message : label('updateError', 'Failed to update note')\n setContentError(message)\n } finally {\n setContentSavingId(null)\n }\n }, [contentEditor, handleUpdateNote, t])\n\n const handleContentEditorKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (!contentEditor.id) return\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (!contentSavingId) void handleContentSave()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n setContentEditor({ id: '', value: '' })\n setContentError(null)\n }\n },\n [contentEditor.id, contentSavingId, handleContentSave],\n )\n\n const handleComposerKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLFormElement>) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n formRef.current?.requestSubmit()\n }\n },\n [],\n )\n\n const handleContentKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>, note: CommentSummary) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n setContentEditor({ id: note.id, value: note.body })\n }\n },\n [],\n )\n\n const noteAuthorLabel = React.useCallback(\n (note: CommentSummary) => {\n if (note.authorUserId && viewerUserId && note.authorUserId === viewerUserId) {\n return youLabel\n }\n return note.authorName ?? note.authorEmail ?? youLabel\n },\n [viewerUserId, youLabel],\n )\n\n const noteAppearanceLabels = React.useMemo<AppearanceSelectorLabels>(\n () => ({\n colorLabel: label('appearance.colorLabel'),\n colorHelp: label('appearance.colorHelp'),\n colorClearLabel: label('appearance.clearColor'),\n iconLabel: label('appearance.iconLabel'),\n iconPlaceholder: label('appearance.iconPlaceholder'),\n iconPickerTriggerLabel: label('appearance.iconPicker'),\n iconSearchPlaceholder: label('appearance.iconSearchPlaceholder'),\n iconSearchEmptyLabel: label('appearance.iconSearchEmpty'),\n iconSuggestionsLabel: label('appearance.iconSuggestions'),\n iconClearLabel: label('appearance.iconClear'),\n previewEmptyLabel: label('appearance.previewEmpty'),\n }),\n [label],\n )\n\n const composerAuthor = React.useMemo(\n () => youLabel,\n [youLabel],\n )\n const composerHasAppearance = Boolean(draftIcon) || Boolean(draftColor)\n const appearanceDialogOpen = appearanceDialogState !== null\n const editingAppearanceNoteId =\n appearanceDialogState?.mode === 'edit' ? appearanceDialogState.noteId : null\n const addNoteShortcutLabel = label('addShortcut', 'Add note \u2318\u23CE / Ctrl+Enter')\n const saveAppearanceShortcutLabel = label('appearance.saveShortcut', 'Save appearance \u2318\u23CE / Ctrl+Enter')\n const composerSubmitLabel = addNoteShortcutLabel\n const appearanceDialogPrimaryLabel = saveAppearanceShortcutLabel\n const appearanceDialogSavingLabel =\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.saving')\n : label('saving', 'Saving note\u2026')\n\n return (\n <div className=\"mt-0 space-y-2\">\n <div\n className={[\n 'overflow-hidden rounded-xl transition-all duration-300 ease-out',\n composerOpen ? 'max-h-[1200px] bg-muted/30 p-4 opacity-100' : 'pointer-events-none max-h-0 p-0 opacity-0',\n ].join(' ')}\n aria-hidden={!composerOpen}\n >\n {composerOpen ? (\n <form\n ref={formRef}\n onSubmit={handleSubmit}\n onKeyDown={handleComposerKeyDown}\n className=\"space-y-3\"\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium\">{label('addLabel')}</h3>\n <div className=\"flex flex-wrap items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setAppearanceDialogError(null)\n setAppearanceDialogState({ mode: 'create', icon: draftIcon, color: draftColor })\n }}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <span className=\"sr-only\">{label('appearance.toggleOpen', 'Customize appearance')}</span>\n <Palette className=\"h-4 w-4\" />\n </Button>\n {disableMarkdown ? null : (\n <Button\n type=\"button\"\n variant={isMarkdownEnabled ? 'secondary' : 'ghost'}\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownEnabled}\n disabled={isSubmitting || isLoading}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting || isLoading}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n {(normalizedEntityOptions.length || normalizedDealOptions.length) ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {normalizedEntityOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-entity-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.entity', 'Assign to customer')}\n </label>\n <Select\n value={selectedEntityId || undefined}\n onValueChange={(next) => setSelectedEntityId(next ?? '')}\n disabled={isSubmitting || isLoading || !normalizedEntityOptions.length}\n >\n <SelectTrigger id=\"note-entity-select\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {normalizedEntityOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {normalizedDealOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-deal-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.deal', 'Link to deal (optional)')}\n </label>\n <Select\n value={selectedDealId || undefined}\n onValueChange={(next) => setSelectedDealId(next ?? '')}\n disabled={isSubmitting || isLoading}\n >\n <SelectTrigger id=\"note-deal-select\">\n <SelectValue placeholder={label('fields.dealPlaceholder', 'No linked deal')} />\n </SelectTrigger>\n <SelectContent>\n {normalizedDealOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n </div>\n ) : null}\n <SwitchableMarkdownInput\n value={draftBody}\n onChange={setDraftBody}\n isMarkdownEnabled={isMarkdownEnabled}\n disableMarkdown={disableMarkdown}\n rows={1}\n placeholder={label('placeholder')}\n textareaRef={textareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n disabled={isSubmitting || isLoading || !hasEntity}\n remarkPlugins={markdownPlugins}\n />\n {composerHasAppearance ? (\n <div className=\"flex flex-wrap items-center justify-between gap-3 rounded-lg border border-dashed border-muted-foreground/40 px-3 py-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-sm\">\n {draftIcon && renderIcon ? (\n <span className=\"inline-flex h-7 w-7 items-center justify-center rounded border border-border bg-muted/50\">\n {renderIcon(draftIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <span className=\"font-semibold text-foreground\">{composerAuthor}</span>\n {draftColor && renderColor ? (\n <span className=\"flex items-center gap-2\">\n {renderColor(draftColor, 'h-3.5 w-3.5 rounded-full border border-border')}\n <span className=\"text-xs font-medium uppercase text-muted-foreground\">{draftColor}</span>\n </span>\n ) : null}\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting}\n >\n {label('appearance.clearAll', 'Clear')}\n </Button>\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n {isSubmitting ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {composerSubmitLabel}\n </Button>\n </div>\n </form>\n ) : null}\n </div>\n\n {loadError ? <ErrorMessage label={loadError} className=\"mt-3\" /> : null}\n\n <div className=\"space-y-3\">\n {!composerOpen && hasVisibleNotes && !onActionChange ? (\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={focusComposer}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <Plus className=\"size-4\" />\n {addActionLabel}\n </Button>\n </div>\n ) : null}\n {isLoading ? (\n <LoadingMessage\n label={label('loading', 'Loading notes\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : hasVisibleNotes ? (\n visibleNotes.map((note) => {\n const author = noteAuthorLabel(note)\n const isAppearanceSaving = appearanceDialogSaving && editingAppearanceNoteId === note.id\n const isEditingContent = contentEditor.id === note.id\n const displayIcon = note.appearanceIcon ?? null\n const displayColor = note.appearanceColor ?? null\n const timestampValue = note.createdAt\n const fallbackTimestampLabel = formatDateTime(note.createdAt) ?? emptyLabel\n return (\n <div key={note.id} className=\"group space-y-2 rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <TimelineItemHeader\n title={author}\n timestamp={timestampValue}\n fallbackTimestampLabel={fallbackTimestampLabel}\n icon={displayIcon}\n color={displayColor}\n renderIcon={renderIcon}\n renderColor={renderColor}\n />\n {note.dealId ? (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <ArrowUpRightSquare className=\"h-3.5 w-3.5\" />\n <a\n href={`/backend/customers/deals/${encodeURIComponent(note.dealId)}`}\n className=\"font-medium text-foreground hover:underline\"\n >\n {note.dealTitle && note.dealTitle.length\n ? note.dealTitle\n : label('linkedDeal', 'Linked deal')}\n </a>\n </div>\n ) : null}\n </div>\n <div\n className={`flex items-center gap-2 transition-opacity ${\n isEditingContent ? 'opacity-100' : 'opacity-100 md:opacity-0 md:group-hover:opacity-100 focus-within:opacity-100'\n }`}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n setAppearanceDialogError(null)\n setAppearanceDialogState({\n mode: 'edit',\n noteId: note.id,\n icon: note.appearanceIcon ?? null,\n color: note.appearanceColor ?? null,\n })\n }}\n disabled={appearanceDialogSaving && editingAppearanceNoteId === note.id}\n >\n {isAppearanceSaving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Palette className=\"h-4 w-4\" />}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n void handleDeleteNote(note)\n }}\n disabled={deletingNoteId === note.id}\n >\n {deletingNoteId === note.id ? (\n <span className=\"relative flex h-4 w-4 items-center justify-center text-destructive\">\n <span className=\"absolute h-4 w-4 animate-spin rounded-full border border-destructive border-t-transparent\" />\n </span>\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n {isEditingContent ? (\n <div className=\"space-y-2\" onKeyDown={handleContentEditorKeyDown}>\n <SwitchableMarkdownInput\n value={contentEditor.value}\n onChange={(nextValue) => setContentEditor((prev) => ({ ...prev, value: nextValue }))}\n isMarkdownEnabled={isMarkdownEnabled}\n disableMarkdown={disableMarkdown}\n rows={3}\n textareaRef={contentTextareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n textareaClassName=\"w-full resize-none overflow-hidden rounded-md border border-border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n editorWrapperClassName=\"w-full rounded-md border border-muted-foreground/20 bg-background p-2\"\n remarkPlugins={markdownPlugins}\n />\n {contentError ? <p className=\"text-xs text-status-error-text\">{contentError}</p> : null}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={handleContentSave} disabled={contentSavingId === note.id}>\n {contentSavingId === note.id ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {label('saving')}\n </>\n ) : (\n inlineLabel('saveShortcut')\n )}\n </Button>\n {disableMarkdown ? null : (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownEnabled}\n className={isMarkdownEnabled ? 'text-primary' : undefined}\n disabled={contentSavingId === note.id}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => setContentEditor({ id: '', value: '' })}\n disabled={contentSavingId === note.id}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n ) : (\n <div\n role=\"button\"\n tabIndex={0}\n className=\"cursor-pointer text-sm\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n onKeyDown={(event) => handleContentKeyDown(event, note)}\n >\n <MarkdownPreview\n remarkPlugins={markdownPlugins}\n className=\"break-words 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\"\n >\n {note.body}\n </MarkdownPreview>\n </div>\n )}\n </div>\n )\n })\n ) : composerOpen ? null : (\n <TabEmptyState\n title={emptyState.title}\n description={emptyState.description}\n action={{\n label: emptyState.actionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || !hasEntity,\n }}\n />\n )}\n {isLoading || (pagedMode ? !hasMore : visibleCount >= notes.length) ? null : (\n <div className=\"flex justify-center\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleLoadMore}>\n {loadMoreLabel}\n </Button>\n </div>\n )}\n </div>\n <AppearanceDialog\n open={appearanceDialogOpen}\n title={\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.edit')\n : label('appearance.toggleOpen', 'Customize appearance')\n }\n icon={appearanceDialogState?.icon ?? null}\n color={appearanceDialogState?.color ?? null}\n labels={noteAppearanceLabels}\n iconSuggestions={iconSuggestions}\n onIconChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, icon: value ?? null } : prev))}\n onColorChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, color: value ?? null } : prev))}\n onSubmit={() => {\n void handleAppearanceDialogSubmit()\n }}\n onClose={handleAppearanceDialogClose}\n isSaving={appearanceDialogSaving}\n errorMessage={appearanceDialogError}\n primaryLabel={appearanceDialogPrimaryLabel}\n savingLabel={appearanceDialogSavingLabel}\n cancelLabel={label('appearance.cancel')}\n />\n {ConfirmDialogElement}\n </div>\n )\n}\n\nexport function NotesSection<C = unknown>(props: NotesSectionProps<C>) {\n const handle = ComponentReplacementHandles.section('ui.detail', 'NotesSection')\n const Resolved = useRegisteredComponent<NotesSectionProps<C>>(\n handle,\n NotesSectionImpl as React.ComponentType<NotesSectionProps<C>>,\n )\n\n return (\n <div data-component-handle={handle}>\n <Resolved {...props} />\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { PluggableList } from 'unified'\nimport type { AppearanceSelectorLabels } from '@open-mercato/core/modules/dictionaries/components/AppearanceSelector'\nimport { AppearanceDialog } from '@open-mercato/core/modules/customers/components/detail/AppearanceDialog'\nimport type { IconOption } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ArrowUpRightSquare, FileCode, Loader2, Palette, Pencil, Plus, Trash2 } from 'lucide-react'\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\nimport { hasMoreFromPage } from '@open-mercato/shared/lib/pagination/load-more'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { flash } from '../FlashMessages'\nimport { surfaceRecordConflict } from '../conflicts'\nimport { SwitchableMarkdownInput } from '../inputs/SwitchableMarkdownInput'\nimport { ErrorMessage } from './ErrorMessage'\nimport { LoadingMessage } from './LoadingMessage'\nimport { TabEmptyState } from './TabEmptyState'\nimport { useConfirmDialog } from '../confirm-dialog'\nimport { formatDateTime } from '@open-mercato/shared/lib/time'\nimport { ComponentReplacementHandles } from '@open-mercato/shared/modules/widgets/component-registry'\nimport { MarkdownPreview } from '../markdown'\nimport { useRegisteredComponent } from '../injection/useRegisteredComponent'\ntype Translator = (key: string, fallback?: string, params?: Record<string, string | number>) => string\n\nconst NOTES_PAGE_SIZE = 20\n\nconst isTestEnv =\n typeof process !== 'undefined' &&\n (process.env.NODE_ENV === 'test' || typeof process.env.JEST_WORKER_ID !== 'undefined')\n\nexport type SectionAction = {\n label: React.ReactNode\n onClick: () => void\n disabled?: boolean\n icon?: React.ReactNode\n}\n\nexport type TabEmptyStateConfig = {\n title: string\n actionLabel: string\n description?: string\n}\n\nexport type CommentSummary = {\n id: string\n body: string\n createdAt: string\n updatedAt?: string | null\n authorUserId?: string | null\n authorName?: string | null\n authorEmail?: string | null\n dealId?: string | null\n dealTitle?: string | null\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesCreatePayload = {\n entityId: string\n body: string\n appearanceIcon: string | null\n appearanceColor: string | null\n dealId?: string | null\n}\n\nexport type NotesUpdatePayload = {\n body?: string\n appearanceIcon?: string | null\n appearanceColor?: string | null\n}\n\nexport type NotesDataAdapter<C = unknown> = {\n list: (params: { entityId: string | null; dealId: string | null; context?: C }) => Promise<CommentSummary[]>\n listPage?: (params: {\n entityId: string | null\n dealId: string | null\n page: number\n pageSize: number\n context?: C\n }) => Promise<{\n items: CommentSummary[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n }>\n create: (params: NotesCreatePayload & { context?: C }) => Promise<Partial<CommentSummary> | void>\n update: (params: { id: string; patch: NotesUpdatePayload; updatedAt?: string | null; context?: C }) => Promise<void>\n delete: (params: { id: string; updatedAt?: string | null; context?: C }) => Promise<void>\n}\n\ntype RenderIconFn = (icon: string, className?: string) => React.ReactNode\ntype RenderColorFn = (color: string, className?: string) => React.ReactNode\n\nlet markdownPluginsPromise: Promise<PluggableList> | null = null\n\nasync function loadMarkdownPlugins(): Promise<PluggableList> {\n if (isTestEnv) return []\n if (!markdownPluginsPromise) {\n markdownPluginsPromise = import('remark-gfm')\n .then((mod) => [mod.default ?? mod] as PluggableList)\n .catch(() => [])\n }\n return markdownPluginsPromise\n}\n\nfunction generateTempId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') return crypto.randomUUID()\n return `tmp_${Math.random().toString(36).slice(2)}`\n}\n\n\n\ntype TimelineItemHeaderProps = {\n title: React.ReactNode\n subtitle?: React.ReactNode\n timestamp?: string | Date | null\n fallbackTimestampLabel?: React.ReactNode\n icon?: string | null\n color?: string | null\n iconSize?: 'sm' | 'md'\n className?: string\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n}\n\nfunction TimelineItemHeader({\n title,\n subtitle,\n timestamp,\n fallbackTimestampLabel,\n icon,\n color,\n iconSize = 'md',\n className,\n renderIcon,\n renderColor,\n}: TimelineItemHeaderProps) {\n const wrapperSize = iconSize === 'sm' ? 'h-6 w-6' : 'h-8 w-8'\n const iconSizeClass = iconSize === 'sm' ? 'h-3.5 w-3.5' : 'h-4 w-4'\n const resolvedTimestamp = React.useMemo(() => {\n if (subtitle) return subtitle\n if (!timestamp) return fallbackTimestampLabel ?? null\n const value = typeof timestamp === 'string' ? timestamp : timestamp.toISOString()\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallbackTimestampLabel ?? null\n const now = Date.now()\n const diff = Math.abs(now - date.getTime())\n const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000\n const relativeLabel = diff <= THIRTY_DAYS_MS ? formatRelativeTime(value) : null\n const absoluteLabel = formatDateTime(value)\n if (relativeLabel) {\n return (\n <span title={absoluteLabel ?? undefined}>\n {relativeLabel}\n </span>\n )\n }\n return absoluteLabel ?? fallbackTimestampLabel ?? null\n }, [fallbackTimestampLabel, subtitle, timestamp])\n\n return (\n <div className={['flex items-start gap-3', className].filter(Boolean).join(' ')}>\n {icon && renderIcon ? (\n <span className={['inline-flex items-center justify-center rounded border border-border bg-muted/50', wrapperSize].join(' ')}>\n {renderIcon(icon, iconSizeClass)}\n </span>\n ) : null}\n <div className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">{title}</span>\n {color && renderColor ? renderColor(color, 'h-3 w-3 rounded-full border border-border') : null}\n </div>\n {resolvedTimestamp ? <div className=\"text-xs text-muted-foreground\">{resolvedTimestamp}</div> : null}\n </div>\n </div>\n )\n}\n\nexport type NotesSectionProps<C = unknown> = {\n entityId: string | null\n dealId?: string | null\n emptyLabel: string\n viewerUserId: string | null\n viewerName?: string | null\n viewerEmail?: string | null\n addActionLabel: string\n emptyState: TabEmptyStateConfig\n onActionChange?: (action: SectionAction | null) => void\n translator?: Translator\n labelPrefix?: string\n inlineLabelPrefix?: string\n onLoadingChange?: (isLoading: boolean) => void\n dealOptions?: Array<{ id: string; label: string }>\n entityOptions?: Array<{ id: string; label: string }>\n dataAdapter: NotesDataAdapter<C>\n dataContext?: C\n renderIcon?: RenderIconFn\n renderColor?: RenderColorFn\n iconSuggestions?: IconOption[]\n readMarkdownPreference?: () => boolean | null\n writeMarkdownPreference?: (value: boolean) => void\n /** Force the plain textarea and hide the markdown toggle. Wins over `forceMarkdown`. */\n disableMarkdown?: boolean\n /**\n * Keep the rich markdown editor active for every note and hide the markdown toggle,\n * so the editor shape cannot be switched. Ignored when `disableMarkdown` is set.\n */\n forceMarkdown?: boolean\n /**\n * Hide the markdown toggle without changing which editor renders \u2014 the seeded\n * `readMarkdownPreference` value stays in effect. Implied by `forceMarkdown`.\n */\n hideMarkdownToggle?: boolean\n /** Hide the appearance (icon/color) affordances: the palette buttons and the appearance dialog. */\n disableAppearance?: boolean\n}\n\nexport function sanitizeHexColor(value: string | null): string | null {\n if (!value) return null\n const trimmed = value.trim()\n return /^#([0-9a-f]{6})$/i.test(trimmed) ? trimmed.toLowerCase() : null\n}\n\nexport function mapCommentSummary(input: unknown): CommentSummary {\n const data = (typeof input === 'object' && input !== null ? input : {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : generateTempId()\n const body = typeof data.body === 'string' ? data.body : ''\n const createdAt =\n typeof data.createdAt === 'string'\n ? data.createdAt\n : typeof data.created_at === 'string'\n ? data.created_at\n : new Date().toISOString()\n const updatedAt =\n typeof data.updatedAt === 'string'\n ? data.updatedAt\n : typeof data.updated_at === 'string'\n ? data.updated_at\n : null\n const authorUserId =\n typeof data.authorUserId === 'string'\n ? data.authorUserId\n : typeof data.author_user_id === 'string'\n ? data.author_user_id\n : null\n const authorName =\n typeof data.authorName === 'string'\n ? data.authorName\n : typeof data.author_name === 'string'\n ? data.author_name\n : null\n const authorEmail =\n typeof data.authorEmail === 'string'\n ? data.authorEmail\n : typeof data.author_email === 'string'\n ? data.author_email\n : null\n const dealId =\n typeof data.dealId === 'string'\n ? data.dealId\n : typeof data.deal_id === 'string'\n ? data.deal_id\n : null\n const dealTitle =\n typeof data.dealTitle === 'string'\n ? data.dealTitle\n : typeof data.deal_title === 'string'\n ? data.deal_title\n : null\n const appearanceIcon =\n typeof data.appearanceIcon === 'string'\n ? data.appearanceIcon\n : typeof data.appearance_icon === 'string'\n ? data.appearance_icon\n : null\n const appearanceColor =\n typeof data.appearanceColor === 'string'\n ? data.appearanceColor\n : typeof data.appearance_color === 'string'\n ? data.appearance_color\n : null\n return {\n id,\n body,\n createdAt,\n updatedAt,\n authorUserId,\n authorName,\n authorEmail,\n dealId,\n dealTitle,\n appearanceIcon,\n appearanceColor,\n }\n}\n\nfunction NotesSectionImpl<C = unknown>({\n entityId,\n dealId,\n emptyLabel,\n viewerUserId,\n viewerName,\n viewerEmail,\n addActionLabel,\n emptyState,\n onActionChange,\n translator,\n labelPrefix = 'customers.people.detail.notes',\n inlineLabelPrefix = 'customers.people.detail.inline',\n onLoadingChange,\n dealOptions,\n entityOptions,\n dataAdapter,\n dataContext,\n renderIcon,\n renderColor,\n iconSuggestions,\n readMarkdownPreference,\n writeMarkdownPreference,\n disableMarkdown,\n forceMarkdown,\n hideMarkdownToggle,\n disableAppearance,\n}: NotesSectionProps<C>) {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const t = React.useMemo<Translator>(() => translator ?? ((key, fallback) => fallback ?? key), [translator])\n const label = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${labelPrefix}.${suffix}`, fallback, params),\n [labelPrefix, t],\n )\n const inlineLabel = React.useCallback(\n (suffix: string, fallback?: string, params?: Record<string, string | number>) =>\n t(`${inlineLabelPrefix}.${suffix}`, fallback, params),\n [inlineLabelPrefix, t],\n )\n const [markdownPlugins, setMarkdownPlugins] = React.useState<PluggableList>([])\n React.useEffect(() => {\n if (isTestEnv) return\n let mounted = true\n void loadMarkdownPlugins().then((plugins) => {\n if (!mounted) return\n setMarkdownPlugins(plugins)\n })\n return () => {\n mounted = false\n }\n }, [])\n\n const normalizedDealOptions = React.useMemo(() => {\n if (!Array.isArray(dealOptions)) return []\n const seen = new Set<string>()\n return dealOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [dealOptions])\n\n const dealLabelMap = React.useMemo(() => {\n const map = new Map<string, string>()\n normalizedDealOptions.forEach((option) => {\n map.set(option.id, option.label)\n })\n return map\n }, [normalizedDealOptions])\n\n const normalizedEntityOptions = React.useMemo(() => {\n if (!Array.isArray(entityOptions)) return []\n const seen = new Set<string>()\n return entityOptions\n .map((option) => {\n if (!option || typeof option !== 'object') return null\n const id = typeof option.id === 'string' ? option.id.trim() : ''\n if (!id || seen.has(id)) return null\n const label =\n typeof option.label === 'string' && option.label.trim().length\n ? option.label.trim()\n : id\n seen.add(id)\n return { id, label }\n })\n .filter((option): option is { id: string; label: string } => !!option)\n }, [entityOptions])\n\n const [selectedDealId, setSelectedDealId] = React.useState<string>(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n return initial\n })\n React.useEffect(() => {\n const initial = typeof dealId === 'string' ? dealId.trim() : ''\n if (initial !== selectedDealId) {\n setSelectedDealId(initial)\n }\n }, [dealId, selectedDealId])\n\n const [selectedEntityId, setSelectedEntityId] = React.useState<string>(() => {\n if (normalizedEntityOptions.length) return normalizedEntityOptions[0].id\n return typeof entityId === 'string' ? entityId : ''\n })\n React.useEffect(() => {\n if (normalizedEntityOptions.length) {\n if (!normalizedEntityOptions.some((option) => option.id === selectedEntityId)) {\n setSelectedEntityId(normalizedEntityOptions[0].id)\n }\n } else {\n const initial = typeof entityId === 'string' ? entityId : ''\n if (initial !== selectedEntityId) {\n setSelectedEntityId(initial)\n }\n }\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedEntityId = React.useMemo(() => {\n if (normalizedEntityOptions.length) return selectedEntityId\n return typeof entityId === 'string' ? entityId : ''\n }, [entityId, normalizedEntityOptions, selectedEntityId])\n\n const resolvedDealId = React.useMemo(() => {\n const trimmed = typeof selectedDealId === 'string' ? selectedDealId.trim() : ''\n return trimmed\n }, [selectedDealId])\n\n const hasEntity = resolvedEntityId.length > 0\n\n const [notes, setNotes] = React.useState<CommentSummary[]>([])\n const [isLoading, setIsLoading] = React.useState<boolean>(() => Boolean(entityId || dealId))\n const [isSubmitting, setIsSubmitting] = React.useState(false)\n const [loadError, setLoadError] = React.useState<string | null>(null)\n const pendingCounterRef = React.useRef(0)\n\n const pushLoading = React.useCallback(() => {\n pendingCounterRef.current += 1\n if (pendingCounterRef.current === 1) {\n onLoadingChange?.(true)\n }\n }, [onLoadingChange])\n\n const popLoading = React.useCallback(() => {\n pendingCounterRef.current = Math.max(0, pendingCounterRef.current - 1)\n if (pendingCounterRef.current === 0) {\n onLoadingChange?.(false)\n }\n }, [onLoadingChange])\n\n const [composerOpen, setComposerOpen] = React.useState(false)\n const [draftBody, setDraftBody] = React.useState('')\n const [draftIcon, setDraftIcon] = React.useState<string | null>(null)\n const [draftColor, setDraftColor] = React.useState<string | null>(null)\n const [isMarkdownEnabled, setIsMarkdownEnabled] = React.useState(false)\n const isMarkdownActive = !disableMarkdown && (Boolean(forceMarkdown) || isMarkdownEnabled)\n const showMarkdownToggle = !disableMarkdown && !forceMarkdown && !hideMarkdownToggle\n const showAppearanceControls = !disableAppearance\n const textareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const formRef = React.useRef<HTMLFormElement | null>(null)\n const focusComposer = React.useCallback(() => {\n if (!hasEntity) return\n setComposerOpen(true)\n window.requestAnimationFrame(() => {\n if (isMarkdownActive) {\n const markdownTextarea = formRef.current?.querySelector('textarea')\n if (markdownTextarea instanceof HTMLTextAreaElement) {\n markdownTextarea.focus()\n markdownTextarea.scrollIntoView({ behavior: 'smooth', block: 'center' })\n return\n }\n }\n const element = textareaRef.current\n if (!element) return\n element.focus()\n element.scrollIntoView({ behavior: 'smooth', block: 'center' })\n })\n }, [formRef, hasEntity, isMarkdownActive])\n const [appearanceDialogState, setAppearanceDialogState] = React.useState<\n | { mode: 'create'; icon: string | null; color: string | null }\n | { mode: 'edit'; noteId: string; icon: string | null; color: string | null }\n | null\n >(null)\n const [appearanceDialogSaving, setAppearanceDialogSaving] = React.useState(false)\n const [appearanceDialogError, setAppearanceDialogError] = React.useState<string | null>(null)\n const [contentEditor, setContentEditor] = React.useState<{ id: string; value: string }>({ id: '', value: '' })\n const [contentSavingId, setContentSavingId] = React.useState<string | null>(null)\n const [contentError, setContentError] = React.useState<string | null>(null)\n const contentTextareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const [visibleCount, setVisibleCount] = React.useState(0)\n const [currentPage, setCurrentPage] = React.useState(1)\n // Short-page termination instead of `currentPage >= totalPages` \u2014 see\n // `hasMoreFromPage`. `/api/customers/comments` is a `makeCrudRoute` list, so\n // a page past the end comes back empty rather than clamped.\n const [hasMore, setHasMore] = React.useState(false)\n const [deletingNoteId, setDeletingNoteId] = React.useState<string | null>(null)\n const pagedMode = typeof dataAdapter.listPage === 'function'\n\n React.useEffect(() => {\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n if (!queryEntityId && !queryDealId) {\n setNotes([])\n setLoadError(null)\n setIsLoading(false)\n setCurrentPage(1)\n setHasMore(false)\n return\n }\n let cancelled = false\n setIsLoading(true)\n setLoadError(null)\n pushLoading()\n async function loadNotes() {\n try {\n if (dataAdapter.listPage) {\n const pageResult = await dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(pageResult.items)\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n return\n }\n const mapped = await dataAdapter.list({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n context: dataContext,\n })\n if (cancelled) return\n setNotes(mapped)\n setCurrentPage(1)\n setHasMore(false)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error ? err.message : label('loadError', 'Failed to load notes.')\n setNotes([])\n setLoadError(message)\n setCurrentPage(1)\n setHasMore(false)\n flash(message, 'error')\n } finally {\n if (!cancelled) setIsLoading(false)\n popLoading()\n }\n }\n loadNotes().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [dataAdapter, dataContext, dealId, entityId, label, popLoading, pushLoading])\n\n const youLabel = label('you', 'You')\n const viewerLabel = React.useMemo(() => viewerName ?? viewerEmail ?? null, [viewerEmail, viewerName])\n\n const handleMarkdownToggle = React.useCallback(() => {\n setIsMarkdownEnabled((prev) => {\n const next = !prev\n if (writeMarkdownPreference) {\n writeMarkdownPreference(next)\n }\n return next\n })\n }, [writeMarkdownPreference])\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (!notes.length) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || isLoading || !hasEntity,\n icon: <Plus className=\"mr-2 h-4 w-4\" />,\n })\n return () => onActionChange(null)\n }, [onActionChange, addActionLabel, focusComposer, hasEntity, isLoading, isSubmitting, notes.length])\n\n const adjustTextareaSize = React.useCallback((element: HTMLTextAreaElement | null) => {\n if (!element) return\n element.style.height = 'auto'\n element.style.height = `${element.scrollHeight}px`\n }, [])\n\n React.useEffect(() => {\n adjustTextareaSize(textareaRef.current)\n }, [adjustTextareaSize, draftBody, isMarkdownActive, composerOpen])\n\n React.useEffect(() => {\n const preference = readMarkdownPreference ? readMarkdownPreference() : null\n if (preference !== null) {\n setIsMarkdownEnabled(preference)\n }\n }, [readMarkdownPreference])\n\n React.useEffect(() => {\n if (pagedMode) {\n setVisibleCount(notes.length)\n return\n }\n if (!notes.length) {\n setVisibleCount(0)\n return\n }\n const baseline = Math.min(5, notes.length)\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(Math.max(prev, baseline), notes.length)\n })\n }, [notes.length, pagedMode])\n\n React.useEffect(() => {\n if (hasEntity) return\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }, [hasEntity])\n\n const visibleNotes = React.useMemo(\n () => (pagedMode ? notes : notes.slice(0, visibleCount)),\n [notes, pagedMode, visibleCount],\n )\n const hasVisibleNotes = React.useMemo(\n () => (pagedMode ? notes.length > 0 : visibleCount > 0),\n [notes.length, pagedMode, visibleCount],\n )\n\n const loadMoreLabel = label('loadMore')\n\n const handleCreateNote = React.useCallback(\n async (input: { body: string; appearanceIcon: string | null; appearanceColor: string | null }) => {\n if (!hasEntity || !resolvedEntityId) {\n flash(label('entityMissing', 'Unable to determine current person.'), 'error')\n return false\n }\n const body = input.body.trim()\n const strippedBody = body\n .replace(/^[\\s#\\-*>_~`|+\\\\\\n\\r]+$/gm, '')\n .replace(/\\s+/g, '')\n if (!body || !strippedBody.length) {\n focusComposer()\n return false\n }\n const icon = input.appearanceIcon && input.appearanceIcon.trim().length ? input.appearanceIcon.trim() : null\n const color = sanitizeHexColor(input.appearanceColor)\n const targetDealId = resolvedDealId.length ? resolvedDealId : null\n const dealLabel = targetDealId ? dealLabelMap.get(targetDealId) ?? null : null\n setIsSubmitting(true)\n pushLoading()\n try {\n const responseBody =\n (await dataAdapter.create({\n entityId: resolvedEntityId,\n body,\n appearanceIcon: icon,\n appearanceColor: color,\n dealId: targetDealId,\n context: dataContext,\n })) ?? {}\n setNotes((prev) => {\n const viewerId = viewerUserId ?? null\n const resolvedAuthorId =\n typeof responseBody?.authorUserId === 'string' ? responseBody.authorUserId : viewerId ?? null\n const resolvedAuthorName = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return youLabel\n }\n return typeof responseBody?.authorName === 'string' ? responseBody.authorName : viewerLabel\n })()\n const resolvedAuthorEmail = (() => {\n if (resolvedAuthorId && viewerId && resolvedAuthorId === viewerId) {\n return viewerEmail ?? null\n }\n return typeof responseBody?.authorEmail === 'string' ? responseBody.authorEmail : null\n })()\n const newNote: CommentSummary = {\n id: typeof responseBody?.id === 'string' ? responseBody.id : generateTempId(),\n body,\n createdAt: new Date().toISOString(),\n authorUserId: resolvedAuthorId,\n authorName: resolvedAuthorName,\n authorEmail: resolvedAuthorEmail,\n dealId: targetDealId,\n dealTitle: dealLabel,\n appearanceIcon: icon,\n appearanceColor: color,\n }\n return [newNote, ...prev]\n })\n setVisibleCount((prev) => Math.max(prev, 1))\n flash(label('success'), 'success')\n return true\n } catch (err) {\n const message = err instanceof Error ? err.message : label('error')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n return false\n } finally {\n setIsSubmitting(false)\n popLoading()\n }\n },\n [dataAdapter, dataContext, dealLabelMap, focusComposer, hasEntity, popLoading, pushLoading, resolvedDealId, resolvedEntityId, t, viewerEmail, viewerLabel, viewerUserId, youLabel],\n )\n\n const handleUpdateNote = React.useCallback(\n async (noteId: string, patch: { body?: string; appearanceIcon?: string | null; appearanceColor?: string | null }) => {\n const sanitizedBody = patch.body\n const sanitizedIcon =\n patch.appearanceIcon !== undefined && patch.appearanceIcon !== null && patch.appearanceIcon.trim().length\n ? patch.appearanceIcon.trim()\n : patch.appearanceIcon === null\n ? null\n : undefined\n const sanitizedColor =\n patch.appearanceColor !== undefined ? sanitizeHexColor(patch.appearanceColor ?? null) : undefined\n const noteUpdatedAt = notes.find((comment) => comment.id === noteId)?.updatedAt ?? null\n try {\n await dataAdapter.update({\n id: noteId,\n patch: {\n body: sanitizedBody,\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n },\n updatedAt: noteUpdatedAt,\n context: dataContext,\n })\n setNotes((prev) => {\n const nextComments = prev.map((comment) => {\n if (comment.id !== noteId) return comment\n const next = { ...comment }\n if (sanitizedBody !== undefined) next.body = sanitizedBody\n if (sanitizedIcon !== undefined) next.appearanceIcon = sanitizedIcon ?? null\n if (sanitizedColor !== undefined) next.appearanceColor = sanitizedColor ?? null\n return next\n })\n return nextComments\n })\n flash(label('updateSuccess'), 'success')\n } catch (error) {\n const message = error instanceof Error ? error.message : label('updateError')\n if (!surfaceRecordConflict(error, t)) flash(message, 'error')\n throw error instanceof Error ? error : new Error(message)\n }\n },\n [dataAdapter, dataContext, notes, t],\n )\n\n const handleDeleteNote = React.useCallback(\n async (note: CommentSummary) => {\n const confirmed = await confirm({\n title: label('deleteConfirm', 'Delete this note? You can restore it using version history.'),\n variant: 'destructive',\n })\n if (!confirmed) return\n setDeletingNoteId(note.id)\n pushLoading()\n try {\n await dataAdapter.delete({ id: note.id, updatedAt: note.updatedAt ?? null, context: dataContext })\n setNotes((prev) => prev.filter((existing) => existing.id !== note.id))\n if (pagedMode) {\n setVisibleCount((prev) => Math.max(0, prev - 1))\n }\n flash(label('deleteSuccess', 'Note deleted'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : label('deleteError', 'Failed to delete note')\n if (!surfaceRecordConflict(err, t)) flash(message, 'error')\n } finally {\n setDeletingNoteId(null)\n popLoading()\n }\n },\n [confirm, dataAdapter, dataContext, label, popLoading, pushLoading, t],\n )\n\n const handleSubmit = React.useCallback(\n async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const created = await handleCreateNote({\n body: draftBody,\n appearanceIcon: draftIcon,\n appearanceColor: draftColor,\n })\n if (created) {\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }\n },\n [draftBody, draftColor, draftIcon, handleCreateNote],\n )\n\n const handleLoadMore = React.useCallback(() => {\n if (pagedMode && dataAdapter.listPage) {\n if (!hasMore || isLoading) return\n const queryEntityId = typeof entityId === 'string' ? entityId : ''\n const queryDealId = typeof dealId === 'string' ? dealId : ''\n setIsLoading(true)\n pushLoading()\n void dataAdapter.listPage({\n entityId: queryEntityId || null,\n dealId: queryDealId || null,\n page: currentPage + 1,\n pageSize: NOTES_PAGE_SIZE,\n context: dataContext,\n })\n .then((pageResult) => {\n setNotes((prev) => {\n const merged = new Map(prev.map((note) => [note.id, note]))\n pageResult.items.forEach((note) => merged.set(note.id, note))\n return Array.from(merged.values())\n })\n setCurrentPage(pageResult.page)\n setHasMore(hasMoreFromPage(pageResult.items.length, NOTES_PAGE_SIZE))\n })\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : label('loadError', 'Failed to load notes.')\n flash(message, 'error')\n })\n .finally(() => {\n setIsLoading(false)\n popLoading()\n })\n return\n }\n setVisibleCount((prev) => {\n if (prev >= notes.length) return prev\n return Math.min(prev + 5, notes.length)\n })\n }, [currentPage, dataAdapter, dataContext, dealId, entityId, flash, hasMore, isLoading, label, notes.length, pagedMode, popLoading, pushLoading])\n\n const handleAppearanceDialogSubmit = React.useCallback(async () => {\n if (!appearanceDialogState) return\n setAppearanceDialogError(null)\n const sanitizedIcon =\n appearanceDialogState.icon && appearanceDialogState.icon.trim().length\n ? appearanceDialogState.icon.trim()\n : null\n const sanitizedColor = sanitizeHexColor(appearanceDialogState.color ?? null)\n if (appearanceDialogState.mode === 'create') {\n setDraftIcon(sanitizedIcon)\n setDraftColor(sanitizedColor)\n setAppearanceDialogState(null)\n return\n }\n setAppearanceDialogSaving(true)\n try {\n await handleUpdateNote(appearanceDialogState.noteId, {\n appearanceIcon: sanitizedIcon,\n appearanceColor: sanitizedColor,\n })\n setAppearanceDialogState(null)\n } catch (err) {\n const message =\n err instanceof Error\n ? err.message\n : label('appearance.error', 'Failed to update appearance.')\n setAppearanceDialogError(message)\n } finally {\n setAppearanceDialogSaving(false)\n }\n }, [appearanceDialogState, handleUpdateNote, t])\n\n const handleAppearanceDialogClose = React.useCallback(() => {\n if (appearanceDialogSaving) return\n setAppearanceDialogState(null)\n setAppearanceDialogError(null)\n }, [appearanceDialogSaving])\n\n const handleContentSave = React.useCallback(async () => {\n if (!contentEditor.id) return\n const trimmed = contentEditor.value.trim()\n if (!trimmed) {\n setContentError(label('updateError', 'Failed to update note'))\n return\n }\n setContentSavingId(contentEditor.id)\n setContentError(null)\n try {\n await handleUpdateNote(contentEditor.id, { body: trimmed })\n setContentEditor({ id: '', value: '' })\n } catch (err) {\n const message =\n err instanceof Error ? err.message : label('updateError', 'Failed to update note')\n setContentError(message)\n } finally {\n setContentSavingId(null)\n }\n }, [contentEditor, handleUpdateNote, t])\n\n const handleContentEditorKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (!contentEditor.id) return\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n if (!contentSavingId) void handleContentSave()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n setContentEditor({ id: '', value: '' })\n setContentError(null)\n }\n },\n [contentEditor.id, contentSavingId, handleContentSave],\n )\n\n const handleComposerKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLFormElement>) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n formRef.current?.requestSubmit()\n }\n },\n [],\n )\n\n const handleContentKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>, note: CommentSummary) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n setContentEditor({ id: note.id, value: note.body })\n }\n },\n [],\n )\n\n const noteAuthorLabel = React.useCallback(\n (note: CommentSummary) => {\n if (note.authorUserId && viewerUserId && note.authorUserId === viewerUserId) {\n return youLabel\n }\n return note.authorName ?? note.authorEmail ?? youLabel\n },\n [viewerUserId, youLabel],\n )\n\n const noteAppearanceLabels = React.useMemo<AppearanceSelectorLabels>(\n () => ({\n colorLabel: label('appearance.colorLabel'),\n colorHelp: label('appearance.colorHelp'),\n colorClearLabel: label('appearance.clearColor'),\n iconLabel: label('appearance.iconLabel'),\n iconPlaceholder: label('appearance.iconPlaceholder'),\n iconPickerTriggerLabel: label('appearance.iconPicker'),\n iconSearchPlaceholder: label('appearance.iconSearchPlaceholder'),\n iconSearchEmptyLabel: label('appearance.iconSearchEmpty'),\n iconSuggestionsLabel: label('appearance.iconSuggestions'),\n iconClearLabel: label('appearance.iconClear'),\n previewEmptyLabel: label('appearance.previewEmpty'),\n }),\n [label],\n )\n\n const composerAuthor = React.useMemo(\n () => youLabel,\n [youLabel],\n )\n const composerHasAppearance = Boolean(draftIcon) || Boolean(draftColor)\n const appearanceDialogOpen = appearanceDialogState !== null\n const editingAppearanceNoteId =\n appearanceDialogState?.mode === 'edit' ? appearanceDialogState.noteId : null\n const addNoteShortcutLabel = label('addShortcut', 'Add note \u2318\u23CE / Ctrl+Enter')\n const saveAppearanceShortcutLabel = label('appearance.saveShortcut', 'Save appearance \u2318\u23CE / Ctrl+Enter')\n const composerSubmitLabel = addNoteShortcutLabel\n const appearanceDialogPrimaryLabel = saveAppearanceShortcutLabel\n const appearanceDialogSavingLabel =\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.saving')\n : label('saving', 'Saving note\u2026')\n\n return (\n <div className=\"mt-0 space-y-2\">\n <div\n className={[\n 'overflow-hidden rounded-xl transition-all duration-300 ease-out',\n composerOpen ? 'max-h-[1200px] bg-muted/30 p-4 opacity-100' : 'pointer-events-none max-h-0 p-0 opacity-0',\n ].join(' ')}\n aria-hidden={!composerOpen}\n >\n {composerOpen ? (\n <form\n ref={formRef}\n onSubmit={handleSubmit}\n onKeyDown={handleComposerKeyDown}\n className=\"space-y-3\"\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium\">{label('addLabel')}</h3>\n <div className=\"flex flex-wrap items-center gap-1\">\n {showAppearanceControls ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setAppearanceDialogError(null)\n setAppearanceDialogState({ mode: 'create', icon: draftIcon, color: draftColor })\n }}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <span className=\"sr-only\">{label('appearance.toggleOpen', 'Customize appearance')}</span>\n <Palette className=\"h-4 w-4\" />\n </Button>\n ) : null}\n {showMarkdownToggle ? (\n <Button\n type=\"button\"\n variant={isMarkdownActive ? 'secondary' : 'ghost'}\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownActive}\n disabled={isSubmitting || isLoading}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n ) : null}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setComposerOpen(false)\n setDraftBody('')\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting || isLoading}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n {(normalizedEntityOptions.length || normalizedDealOptions.length) ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {normalizedEntityOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-entity-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.entity', 'Assign to customer')}\n </label>\n <Select\n value={selectedEntityId || undefined}\n onValueChange={(next) => setSelectedEntityId(next ?? '')}\n disabled={isSubmitting || isLoading || !normalizedEntityOptions.length}\n >\n <SelectTrigger id=\"note-entity-select\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {normalizedEntityOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {normalizedDealOptions.length ? (\n <div className=\"flex flex-col gap-1\">\n <label\n htmlFor=\"note-deal-select\"\n className=\"text-xs font-medium text-muted-foreground\"\n >\n {label('fields.deal', 'Link to deal (optional)')}\n </label>\n <Select\n value={selectedDealId || undefined}\n onValueChange={(next) => setSelectedDealId(next ?? '')}\n disabled={isSubmitting || isLoading}\n >\n <SelectTrigger id=\"note-deal-select\">\n <SelectValue placeholder={label('fields.dealPlaceholder', 'No linked deal')} />\n </SelectTrigger>\n <SelectContent>\n {normalizedDealOptions.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n </div>\n ) : null}\n <SwitchableMarkdownInput\n value={draftBody}\n onChange={setDraftBody}\n isMarkdownEnabled={isMarkdownActive}\n disableMarkdown={disableMarkdown}\n rows={1}\n placeholder={label('placeholder')}\n textareaRef={textareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n disabled={isSubmitting || isLoading || !hasEntity}\n remarkPlugins={markdownPlugins}\n />\n {composerHasAppearance ? (\n <div className=\"flex flex-wrap items-center justify-between gap-3 rounded-lg border border-dashed border-muted-foreground/40 px-3 py-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-sm\">\n {draftIcon && renderIcon ? (\n <span className=\"inline-flex h-7 w-7 items-center justify-center rounded border border-border bg-muted/50\">\n {renderIcon(draftIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <span className=\"font-semibold text-foreground\">{composerAuthor}</span>\n {draftColor && renderColor ? (\n <span className=\"flex items-center gap-2\">\n {renderColor(draftColor, 'h-3.5 w-3.5 rounded-full border border-border')}\n <span className=\"text-xs font-medium uppercase text-muted-foreground\">{draftColor}</span>\n </span>\n ) : null}\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setDraftIcon(null)\n setDraftColor(null)\n }}\n disabled={isSubmitting}\n >\n {label('appearance.clearAll', 'Clear')}\n </Button>\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n {isSubmitting ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" /> : null}\n {composerSubmitLabel}\n </Button>\n </div>\n </form>\n ) : null}\n </div>\n\n {loadError ? <ErrorMessage label={loadError} className=\"mt-3\" /> : null}\n\n <div className=\"space-y-3\">\n {!composerOpen && hasVisibleNotes && !onActionChange ? (\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={focusComposer}\n disabled={isSubmitting || isLoading || !hasEntity}\n >\n <Plus className=\"size-4\" />\n {addActionLabel}\n </Button>\n </div>\n ) : null}\n {isLoading ? (\n <LoadingMessage\n label={label('loading', 'Loading notes\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : hasVisibleNotes ? (\n visibleNotes.map((note) => {\n const author = noteAuthorLabel(note)\n const isAppearanceSaving = appearanceDialogSaving && editingAppearanceNoteId === note.id\n const isEditingContent = contentEditor.id === note.id\n const displayIcon = note.appearanceIcon ?? null\n const displayColor = note.appearanceColor ?? null\n const timestampValue = note.createdAt\n const fallbackTimestampLabel = formatDateTime(note.createdAt) ?? emptyLabel\n return (\n <div key={note.id} className=\"group space-y-2 rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <TimelineItemHeader\n title={author}\n timestamp={timestampValue}\n fallbackTimestampLabel={fallbackTimestampLabel}\n icon={displayIcon}\n color={displayColor}\n renderIcon={renderIcon}\n renderColor={renderColor}\n />\n {note.dealId ? (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <ArrowUpRightSquare className=\"h-3.5 w-3.5\" />\n <a\n href={`/backend/customers/deals/${encodeURIComponent(note.dealId)}`}\n className=\"font-medium text-foreground hover:underline\"\n >\n {note.dealTitle && note.dealTitle.length\n ? note.dealTitle\n : label('linkedDeal', 'Linked deal')}\n </a>\n </div>\n ) : null}\n </div>\n <div\n className={`flex items-center gap-2 transition-opacity ${\n isEditingContent ? 'opacity-100' : 'opacity-100 md:opacity-0 md:group-hover:opacity-100 focus-within:opacity-100'\n }`}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n {showAppearanceControls ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n setAppearanceDialogError(null)\n setAppearanceDialogState({\n mode: 'edit',\n noteId: note.id,\n icon: note.appearanceIcon ?? null,\n color: note.appearanceColor ?? null,\n })\n }}\n disabled={appearanceDialogSaving && editingAppearanceNoteId === note.id}\n >\n {isAppearanceSaving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Palette className=\"h-4 w-4\" />}\n </Button>\n ) : null}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event) => {\n event.stopPropagation()\n void handleDeleteNote(note)\n }}\n disabled={deletingNoteId === note.id}\n >\n {deletingNoteId === note.id ? (\n <span className=\"relative flex h-4 w-4 items-center justify-center text-destructive\">\n <span className=\"absolute h-4 w-4 animate-spin rounded-full border border-destructive border-t-transparent\" />\n </span>\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n {isEditingContent ? (\n <div className=\"space-y-2\" onKeyDown={handleContentEditorKeyDown}>\n <SwitchableMarkdownInput\n value={contentEditor.value}\n onChange={(nextValue) => setContentEditor((prev) => ({ ...prev, value: nextValue }))}\n isMarkdownEnabled={isMarkdownActive}\n disableMarkdown={disableMarkdown}\n rows={3}\n textareaRef={contentTextareaRef}\n onTextareaInput={(event) => adjustTextareaSize(event.currentTarget)}\n textareaClassName=\"w-full resize-none overflow-hidden rounded-md border border-border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n editorWrapperClassName=\"w-full rounded-md border border-muted-foreground/20 bg-background p-2\"\n remarkPlugins={markdownPlugins}\n />\n {contentError ? <p className=\"text-xs text-status-error-text\">{contentError}</p> : null}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={handleContentSave} disabled={contentSavingId === note.id}>\n {contentSavingId === note.id ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {label('saving')}\n </>\n ) : (\n inlineLabel('saveShortcut')\n )}\n </Button>\n {showMarkdownToggle ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleMarkdownToggle}\n aria-pressed={isMarkdownActive}\n className={isMarkdownActive ? 'text-primary' : undefined}\n disabled={contentSavingId === note.id}\n >\n <FileCode className=\"h-4 w-4\" />\n </Button>\n ) : null}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => setContentEditor({ id: '', value: '' })}\n disabled={contentSavingId === note.id}\n >\n {inlineLabel('cancel')}\n </Button>\n </div>\n </div>\n ) : (\n <div\n role=\"button\"\n tabIndex={0}\n className=\"cursor-pointer text-sm\"\n onClick={() => setContentEditor({ id: note.id, value: note.body })}\n onKeyDown={(event) => handleContentKeyDown(event, note)}\n >\n <MarkdownPreview\n remarkPlugins={markdownPlugins}\n className=\"break-words 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\"\n >\n {note.body}\n </MarkdownPreview>\n </div>\n )}\n </div>\n )\n })\n ) : composerOpen ? null : (\n <TabEmptyState\n title={emptyState.title}\n description={emptyState.description}\n action={{\n label: emptyState.actionLabel,\n onClick: focusComposer,\n disabled: isSubmitting || !hasEntity,\n }}\n />\n )}\n {isLoading || (pagedMode ? !hasMore : visibleCount >= notes.length) ? null : (\n <div className=\"flex justify-center\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleLoadMore}>\n {loadMoreLabel}\n </Button>\n </div>\n )}\n </div>\n {showAppearanceControls ? (\n <AppearanceDialog\n open={appearanceDialogOpen}\n title={\n appearanceDialogState?.mode === 'edit'\n ? label('appearance.edit')\n : label('appearance.toggleOpen', 'Customize appearance')\n }\n icon={appearanceDialogState?.icon ?? null}\n color={appearanceDialogState?.color ?? null}\n labels={noteAppearanceLabels}\n iconSuggestions={iconSuggestions}\n onIconChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, icon: value ?? null } : prev))}\n onColorChange={(value) => setAppearanceDialogState((prev) => (prev ? { ...prev, color: value ?? null } : prev))}\n onSubmit={() => {\n void handleAppearanceDialogSubmit()\n }}\n onClose={handleAppearanceDialogClose}\n isSaving={appearanceDialogSaving}\n errorMessage={appearanceDialogError}\n primaryLabel={appearanceDialogPrimaryLabel}\n savingLabel={appearanceDialogSavingLabel}\n cancelLabel={label('appearance.cancel')}\n />\n ) : null}\n {ConfirmDialogElement}\n </div>\n )\n}\n\nexport function NotesSection<C = unknown>(props: NotesSectionProps<C>) {\n const handle = ComponentReplacementHandles.section('ui.detail', 'NotesSection')\n const Resolved = useRegisteredComponent<NotesSectionProps<C>>(\n handle,\n NotesSectionImpl as React.ComponentType<NotesSectionProps<C>>,\n )\n\n return (\n <div data-component-handle={handle}>\n <Resolved {...props} />\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["label"]
7
7
  }
@@ -6,6 +6,7 @@ import {
6
6
  AlertTriangle,
7
7
  Apple,
8
8
  Archive,
9
+ AtSign,
9
10
  Award,
10
11
  BadgeCheck,
11
12
  Ban,
@@ -16,6 +17,7 @@ import {
16
17
  Bolt,
17
18
  Book,
18
19
  Bookmark,
20
+ Bot,
19
21
  Box,
20
22
  Boxes,
21
23
  Briefcase,
@@ -167,6 +169,7 @@ const LUCIDE_ICON_REGISTRY = {
167
169
  "alert-triangle": AlertTriangle,
168
170
  "apple": Apple,
169
171
  "archive": Archive,
172
+ "at-sign": AtSign,
170
173
  "award": Award,
171
174
  "badge-check": BadgeCheck,
172
175
  "ban": Ban,
@@ -177,6 +180,7 @@ const LUCIDE_ICON_REGISTRY = {
177
180
  "bolt": Bolt,
178
181
  "book": Book,
179
182
  "bookmark": Bookmark,
183
+ "bot": Bot,
180
184
  "box": Box,
181
185
  "boxes": Boxes,
182
186
  "briefcase": Briefcase,