@open-mercato/core 0.4.11-develop.1436.ff2df4355a → 0.4.11-develop.1447.556dc05740
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.
|
@@ -292,250 +292,245 @@ function DealDetailPage({ params }) {
|
|
|
292
292
|
const companiesSummaryLabel = data.companies.length === 1 ? t("customers.deals.detail.companiesSummaryOne") : t("customers.deals.detail.companiesSummaryMany", void 0, { count: data.companies.length });
|
|
293
293
|
const viewer = data.viewer ?? null;
|
|
294
294
|
return /* @__PURE__ */ jsxs(Page, { children: [
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
{
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
previewData: {
|
|
317
|
-
title: data.deal.title || t("customers.deals.detail.untitled", "Untitled deal"),
|
|
318
|
-
status: data.deal.status ? statusLabel : void 0,
|
|
319
|
-
metadata: Object.keys(dealPreviewMetadata).length > 0 ? dealPreviewMetadata : void 0
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
viewHref: `/backend/customers/deals/${data.deal.id}`,
|
|
323
|
-
defaultValues: {
|
|
324
|
-
sourceEntityType: "customers.deal",
|
|
325
|
-
sourceEntityId: data.deal.id
|
|
295
|
+
/* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
296
|
+
/* @__PURE__ */ jsx(
|
|
297
|
+
FormHeader,
|
|
298
|
+
{
|
|
299
|
+
mode: "detail",
|
|
300
|
+
backHref: "/backend/customers/deals",
|
|
301
|
+
backLabel: t("customers.deals.detail.backToList", "Back to deals"),
|
|
302
|
+
utilityActions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
303
|
+
/* @__PURE__ */ jsx(
|
|
304
|
+
SendObjectMessageDialog,
|
|
305
|
+
{
|
|
306
|
+
object: {
|
|
307
|
+
entityModule: "customers",
|
|
308
|
+
entityType: "deal",
|
|
309
|
+
entityId: data.deal.id,
|
|
310
|
+
sourceEntityType: "customers.deal",
|
|
311
|
+
sourceEntityId: data.deal.id,
|
|
312
|
+
previewData: {
|
|
313
|
+
title: data.deal.title || t("customers.deals.detail.untitled", "Untitled deal"),
|
|
314
|
+
status: data.deal.status ? statusLabel : void 0,
|
|
315
|
+
metadata: Object.keys(dealPreviewMetadata).length > 0 ? dealPreviewMetadata : void 0
|
|
326
316
|
}
|
|
317
|
+
},
|
|
318
|
+
viewHref: `/backend/customers/deals/${data.deal.id}`,
|
|
319
|
+
defaultValues: {
|
|
320
|
+
sourceEntityType: "customers.deal",
|
|
321
|
+
sourceEntityId: data.deal.id
|
|
327
322
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
323
|
+
}
|
|
324
|
+
),
|
|
325
|
+
/* @__PURE__ */ jsx(
|
|
326
|
+
VersionHistoryAction,
|
|
327
|
+
{
|
|
328
|
+
config: { resourceKind: "customers.deal", resourceId: data.deal.id },
|
|
329
|
+
t
|
|
330
|
+
}
|
|
331
|
+
)
|
|
332
|
+
] }),
|
|
333
|
+
title: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
334
|
+
/* @__PURE__ */ jsx("span", { children: data.deal.title || t("customers.deals.detail.untitled", "Untitled deal") }),
|
|
335
|
+
/* @__PURE__ */ jsxs(
|
|
336
|
+
Button,
|
|
337
|
+
{
|
|
338
|
+
type: "button",
|
|
339
|
+
variant: "ghost",
|
|
340
|
+
size: "sm",
|
|
341
|
+
className: "gap-1 text-muted-foreground hover:text-foreground",
|
|
342
|
+
onClick: scrollToDealSettings,
|
|
343
|
+
children: [
|
|
344
|
+
/* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4", "aria-hidden": true }),
|
|
345
|
+
/* @__PURE__ */ jsx(MousePointerClick, { className: "h-4 w-4", "aria-hidden": true }),
|
|
346
|
+
/* @__PURE__ */ jsx("span", { children: t("customers.deals.detail.goToSettings", "Edit deal details") })
|
|
347
|
+
]
|
|
348
|
+
}
|
|
349
|
+
)
|
|
350
|
+
] }),
|
|
351
|
+
subtitle: t("customers.deals.detail.summary", void 0, {
|
|
352
|
+
status: statusLabel,
|
|
353
|
+
pipeline: pipelineLabel ?? t("customers.deals.detail.noPipeline", "No pipeline")
|
|
354
|
+
}),
|
|
355
|
+
onDelete: handleDelete,
|
|
356
|
+
isDeleting,
|
|
357
|
+
deleteLabel: t("ui.actions.delete", "Delete")
|
|
358
|
+
}
|
|
359
|
+
),
|
|
360
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]", children: [
|
|
361
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
362
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", children: [
|
|
363
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-4 text-sm font-semibold uppercase text-muted-foreground", children: t("customers.deals.detail.highlights", "Highlights") }),
|
|
364
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [
|
|
365
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
366
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.value", "Deal value") }),
|
|
367
|
+
/* @__PURE__ */ jsx("p", { className: "text-base font-semibold text-foreground", children: valueLabel })
|
|
368
|
+
] }),
|
|
369
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
370
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.probability", "Probability") }),
|
|
371
|
+
/* @__PURE__ */ jsx("p", { className: "text-base font-semibold text-foreground", children: probabilityLabel })
|
|
372
|
+
] }),
|
|
373
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
374
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.status", "Status") }),
|
|
375
|
+
/* @__PURE__ */ jsxs("p", { className: "text-base text-foreground flex items-center gap-2", children: [
|
|
376
|
+
statusDictEntry?.color ? renderDictionaryColor(statusDictEntry.color) : null,
|
|
377
|
+
statusDictEntry?.icon ? renderDictionaryIcon(statusDictEntry.icon) : null,
|
|
378
|
+
statusLabel
|
|
379
|
+
] })
|
|
380
|
+
] }),
|
|
381
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
382
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.pipeline", "Pipeline stage") }),
|
|
383
|
+
/* @__PURE__ */ jsxs("p", { className: "text-base text-foreground flex items-center gap-2", children: [
|
|
384
|
+
pipelineDictEntry?.color ? renderDictionaryColor(pipelineDictEntry.color) : null,
|
|
385
|
+
pipelineDictEntry?.icon ? renderDictionaryIcon(pipelineDictEntry.icon) : null,
|
|
386
|
+
pipelineLabel ?? t("customers.deals.detail.noValue", "Not provided")
|
|
387
|
+
] })
|
|
388
|
+
] }),
|
|
389
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
390
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.expectedClose", "Expected close") }),
|
|
391
|
+
/* @__PURE__ */ jsx("p", { className: "text-base text-foreground", children: expectedCloseLabel })
|
|
392
|
+
] })
|
|
393
|
+
] })
|
|
394
|
+
] }),
|
|
395
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", children: [
|
|
396
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
|
|
397
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: tabs.map((tab) => /* @__PURE__ */ jsx(
|
|
398
|
+
Button,
|
|
331
399
|
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
400
|
+
variant: "ghost",
|
|
401
|
+
size: "sm",
|
|
402
|
+
onClick: () => setActiveTab(tab.id),
|
|
403
|
+
className: `h-auto rounded-none border-b-2 px-0 py-1 ${activeTab === tab.id ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent"}`,
|
|
404
|
+
children: tab.label
|
|
405
|
+
},
|
|
406
|
+
tab.id
|
|
407
|
+
)) }),
|
|
408
|
+
sectionAction ? /* @__PURE__ */ jsxs(
|
|
340
409
|
Button,
|
|
341
410
|
{
|
|
342
411
|
type: "button",
|
|
343
|
-
variant: "ghost",
|
|
344
412
|
size: "sm",
|
|
345
|
-
|
|
346
|
-
onClick:
|
|
413
|
+
disabled: sectionAction.disabled,
|
|
414
|
+
onClick: handleSectionAction,
|
|
347
415
|
children: [
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
/* @__PURE__ */ jsx("span", { children: t("customers.deals.detail.goToSettings", "Edit deal details") })
|
|
416
|
+
sectionAction.icon ?? null,
|
|
417
|
+
sectionAction.label
|
|
351
418
|
]
|
|
352
419
|
}
|
|
353
|
-
)
|
|
354
|
-
] }),
|
|
355
|
-
subtitle: t("customers.deals.detail.summary", void 0, {
|
|
356
|
-
status: statusLabel,
|
|
357
|
-
pipeline: pipelineLabel ?? t("customers.deals.detail.noPipeline", "No pipeline")
|
|
358
|
-
}),
|
|
359
|
-
onDelete: handleDelete,
|
|
360
|
-
isDeleting,
|
|
361
|
-
deleteLabel: t("ui.actions.delete", "Delete")
|
|
362
|
-
}
|
|
363
|
-
),
|
|
364
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]", children: [
|
|
365
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
366
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", children: [
|
|
367
|
-
/* @__PURE__ */ jsx("h2", { className: "mb-4 text-sm font-semibold uppercase text-muted-foreground", children: t("customers.deals.detail.highlights", "Highlights") }),
|
|
368
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [
|
|
369
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
370
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.value", "Deal value") }),
|
|
371
|
-
/* @__PURE__ */ jsx("p", { className: "text-base font-semibold text-foreground", children: valueLabel })
|
|
372
|
-
] }),
|
|
373
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
374
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.probability", "Probability") }),
|
|
375
|
-
/* @__PURE__ */ jsx("p", { className: "text-base font-semibold text-foreground", children: probabilityLabel })
|
|
376
|
-
] }),
|
|
377
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
378
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.status", "Status") }),
|
|
379
|
-
/* @__PURE__ */ jsxs("p", { className: "text-base text-foreground flex items-center gap-2", children: [
|
|
380
|
-
statusDictEntry?.color ? renderDictionaryColor(statusDictEntry.color) : null,
|
|
381
|
-
statusDictEntry?.icon ? renderDictionaryIcon(statusDictEntry.icon) : null,
|
|
382
|
-
statusLabel
|
|
383
|
-
] })
|
|
384
|
-
] }),
|
|
385
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
386
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.pipeline", "Pipeline stage") }),
|
|
387
|
-
/* @__PURE__ */ jsxs("p", { className: "text-base text-foreground flex items-center gap-2", children: [
|
|
388
|
-
pipelineDictEntry?.color ? renderDictionaryColor(pipelineDictEntry.color) : null,
|
|
389
|
-
pipelineDictEntry?.icon ? renderDictionaryIcon(pipelineDictEntry.icon) : null,
|
|
390
|
-
pipelineLabel ?? t("customers.deals.detail.noValue", "Not provided")
|
|
391
|
-
] })
|
|
392
|
-
] }),
|
|
393
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
394
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase text-muted-foreground", children: t("customers.deals.detail.fields.expectedClose", "Expected close") }),
|
|
395
|
-
/* @__PURE__ */ jsx("p", { className: "text-base text-foreground", children: expectedCloseLabel })
|
|
396
|
-
] })
|
|
397
|
-
] })
|
|
420
|
+
) : null
|
|
398
421
|
] }),
|
|
422
|
+
activeTab === "notes" ? /* @__PURE__ */ jsx(
|
|
423
|
+
NotesSection,
|
|
424
|
+
{
|
|
425
|
+
entityId: null,
|
|
426
|
+
dealId: data.deal.id,
|
|
427
|
+
dealOptions,
|
|
428
|
+
entityOptions,
|
|
429
|
+
emptyLabel: t("customers.deals.detail.notesEmpty", "No notes yet."),
|
|
430
|
+
viewerUserId: viewer?.userId ?? null,
|
|
431
|
+
viewerName: viewer?.name ?? null,
|
|
432
|
+
viewerEmail: viewer?.email ?? null,
|
|
433
|
+
addActionLabel: t("customers.deals.detail.notesAdd", "Add note"),
|
|
434
|
+
emptyState: {
|
|
435
|
+
title: t("customers.deals.detail.notesEmptyTitle", "Keep everyone in the loop"),
|
|
436
|
+
actionLabel: t("customers.deals.detail.notesEmptyAction", "Add a note")
|
|
437
|
+
},
|
|
438
|
+
onActionChange: setSectionAction,
|
|
439
|
+
translator: detailTranslator,
|
|
440
|
+
onLoadingChange: handleNotesLoadingChange,
|
|
441
|
+
dataAdapter: notesAdapter,
|
|
442
|
+
renderIcon: renderDictionaryIcon,
|
|
443
|
+
renderColor: renderDictionaryColor,
|
|
444
|
+
iconSuggestions: ICON_SUGGESTIONS,
|
|
445
|
+
readMarkdownPreference: readMarkdownPreferenceCookie,
|
|
446
|
+
writeMarkdownPreference: writeMarkdownPreferenceCookie
|
|
447
|
+
}
|
|
448
|
+
) : null,
|
|
449
|
+
activeTab === "activities" ? /* @__PURE__ */ jsx(
|
|
450
|
+
ActivitiesSection,
|
|
451
|
+
{
|
|
452
|
+
entityId: null,
|
|
453
|
+
dealId: data.deal.id,
|
|
454
|
+
dealOptions,
|
|
455
|
+
entityOptions,
|
|
456
|
+
defaultEntityId: defaultEntityId ?? void 0,
|
|
457
|
+
addActionLabel: t("customers.deals.detail.activitiesAdd", "Log activity"),
|
|
458
|
+
emptyState: {
|
|
459
|
+
title: t("customers.deals.detail.activitiesEmptyTitle", "No activities yet"),
|
|
460
|
+
actionLabel: t("customers.deals.detail.activitiesEmptyAction", "Add an activity")
|
|
461
|
+
},
|
|
462
|
+
onActionChange: setSectionAction,
|
|
463
|
+
onLoadingChange: handleActivitiesLoadingChange
|
|
464
|
+
}
|
|
465
|
+
) : null
|
|
466
|
+
] }),
|
|
467
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
|
|
399
468
|
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", children: [
|
|
400
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
401
|
-
/* @__PURE__ */ jsx("
|
|
402
|
-
|
|
403
|
-
{
|
|
404
|
-
variant: "ghost",
|
|
405
|
-
size: "sm",
|
|
406
|
-
onClick: () => setActiveTab(tab.id),
|
|
407
|
-
className: `h-auto rounded-none border-b-2 px-0 py-1 ${activeTab === tab.id ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent"}`,
|
|
408
|
-
children: tab.label
|
|
409
|
-
},
|
|
410
|
-
tab.id
|
|
411
|
-
)) }),
|
|
412
|
-
sectionAction ? /* @__PURE__ */ jsxs(
|
|
413
|
-
Button,
|
|
414
|
-
{
|
|
415
|
-
type: "button",
|
|
416
|
-
size: "sm",
|
|
417
|
-
disabled: sectionAction.disabled,
|
|
418
|
-
onClick: handleSectionAction,
|
|
419
|
-
children: [
|
|
420
|
-
sectionAction.icon ?? null,
|
|
421
|
-
sectionAction.label
|
|
422
|
-
]
|
|
423
|
-
}
|
|
424
|
-
) : null
|
|
469
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 space-y-1", children: [
|
|
470
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: t("customers.deals.detail.peopleSection", "People") }),
|
|
471
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: peopleSummaryLabel })
|
|
425
472
|
] }),
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
{
|
|
429
|
-
|
|
430
|
-
dealId: data.deal.id,
|
|
431
|
-
dealOptions,
|
|
432
|
-
entityOptions,
|
|
433
|
-
emptyLabel: t("customers.deals.detail.notesEmpty", "No notes yet."),
|
|
434
|
-
viewerUserId: viewer?.userId ?? null,
|
|
435
|
-
viewerName: viewer?.name ?? null,
|
|
436
|
-
viewerEmail: viewer?.email ?? null,
|
|
437
|
-
addActionLabel: t("customers.deals.detail.notesAdd", "Add note"),
|
|
438
|
-
emptyState: {
|
|
439
|
-
title: t("customers.deals.detail.notesEmptyTitle", "Keep everyone in the loop"),
|
|
440
|
-
actionLabel: t("customers.deals.detail.notesEmptyAction", "Add a note")
|
|
441
|
-
},
|
|
442
|
-
onActionChange: setSectionAction,
|
|
443
|
-
translator: detailTranslator,
|
|
444
|
-
onLoadingChange: handleNotesLoadingChange,
|
|
445
|
-
dataAdapter: notesAdapter,
|
|
446
|
-
renderIcon: renderDictionaryIcon,
|
|
447
|
-
renderColor: renderDictionaryColor,
|
|
448
|
-
iconSuggestions: ICON_SUGGESTIONS,
|
|
449
|
-
readMarkdownPreference: readMarkdownPreferenceCookie,
|
|
450
|
-
writeMarkdownPreference: writeMarkdownPreferenceCookie
|
|
451
|
-
}
|
|
452
|
-
) : null,
|
|
453
|
-
activeTab === "activities" ? /* @__PURE__ */ jsx(
|
|
454
|
-
ActivitiesSection,
|
|
455
|
-
{
|
|
456
|
-
entityId: null,
|
|
457
|
-
dealId: data.deal.id,
|
|
458
|
-
dealOptions,
|
|
459
|
-
entityOptions,
|
|
460
|
-
defaultEntityId: defaultEntityId ?? void 0,
|
|
461
|
-
addActionLabel: t("customers.deals.detail.activitiesAdd", "Log activity"),
|
|
462
|
-
emptyState: {
|
|
463
|
-
title: t("customers.deals.detail.activitiesEmptyTitle", "No activities yet"),
|
|
464
|
-
actionLabel: t("customers.deals.detail.activitiesEmptyAction", "Add an activity")
|
|
465
|
-
},
|
|
466
|
-
onActionChange: setSectionAction,
|
|
467
|
-
onLoadingChange: handleActivitiesLoadingChange
|
|
468
|
-
}
|
|
469
|
-
) : null
|
|
473
|
+
data.people.length ? /* @__PURE__ */ jsx("ul", { className: "space-y-2 text-sm", children: data.people.map((person) => /* @__PURE__ */ jsxs("li", { className: "flex flex-col gap-1", children: [
|
|
474
|
+
/* @__PURE__ */ jsx(Link, { href: `/backend/customers/people-v2/${encodeURIComponent(person.id)}`, className: "font-medium text-foreground hover:underline", children: person.label }),
|
|
475
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: person.subtitle ?? t("customers.deals.detail.peopleNoDetails", "No additional details") })
|
|
476
|
+
] }, person.id)) }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("customers.deals.detail.noPeople", "No people linked to this deal yet.") })
|
|
470
477
|
] }),
|
|
471
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
472
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
473
|
-
/* @__PURE__ */
|
|
474
|
-
|
|
475
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: peopleSummaryLabel })
|
|
476
|
-
] }),
|
|
477
|
-
data.people.length ? /* @__PURE__ */ jsx("ul", { className: "space-y-2 text-sm", children: data.people.map((person) => /* @__PURE__ */ jsxs("li", { className: "flex flex-col gap-1", children: [
|
|
478
|
-
/* @__PURE__ */ jsx(Link, { href: `/backend/customers/people-v2/${encodeURIComponent(person.id)}`, className: "font-medium text-foreground hover:underline", children: person.label }),
|
|
479
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: person.subtitle ?? t("customers.deals.detail.peopleNoDetails", "No additional details") })
|
|
480
|
-
] }, person.id)) }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("customers.deals.detail.noPeople", "No people linked to this deal yet.") })
|
|
478
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", children: [
|
|
479
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 space-y-1", children: [
|
|
480
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: t("customers.deals.detail.companiesSection", "Companies") }),
|
|
481
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: companiesSummaryLabel })
|
|
481
482
|
] }),
|
|
482
|
-
/* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
] }),
|
|
487
|
-
data.companies.length ? /* @__PURE__ */ jsx("ul", { className: "space-y-2 text-sm", children: data.companies.map((company) => /* @__PURE__ */ jsxs("li", { className: "flex flex-col gap-1", children: [
|
|
488
|
-
/* @__PURE__ */ jsx(Link, { href: `/backend/customers/companies-v2/${encodeURIComponent(company.id)}`, className: "font-medium text-foreground hover:underline", children: company.label }),
|
|
489
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: company.subtitle ?? t("customers.deals.detail.companiesNoDetails", "No additional details") })
|
|
490
|
-
] }, company.id)) }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("customers.deals.detail.noCompanies", "No companies linked to this deal yet.") })
|
|
491
|
-
] })
|
|
483
|
+
data.companies.length ? /* @__PURE__ */ jsx("ul", { className: "space-y-2 text-sm", children: data.companies.map((company) => /* @__PURE__ */ jsxs("li", { className: "flex flex-col gap-1", children: [
|
|
484
|
+
/* @__PURE__ */ jsx(Link, { href: `/backend/customers/companies-v2/${encodeURIComponent(company.id)}`, className: "font-medium text-foreground hover:underline", children: company.label }),
|
|
485
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: company.subtitle ?? t("customers.deals.detail.companiesNoDetails", "No additional details") })
|
|
486
|
+
] }, company.id)) }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("customers.deals.detail.noCompanies", "No companies linked to this deal yet.") })
|
|
492
487
|
] })
|
|
493
|
-
] })
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
)
|
|
525
|
-
|
|
526
|
-
onSubmit: handleFormSubmit,
|
|
527
|
-
onCancel: () => setReloadToken((token) => token + 1),
|
|
528
|
-
onDelete: handleDelete,
|
|
529
|
-
isSubmitting: isSaving || isDeleting
|
|
488
|
+
] })
|
|
489
|
+
] }),
|
|
490
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxs(
|
|
491
|
+
"div",
|
|
492
|
+
{
|
|
493
|
+
ref: dealSettingsRef,
|
|
494
|
+
id: "deal-settings",
|
|
495
|
+
className: "rounded-lg border bg-card p-4",
|
|
496
|
+
children: [
|
|
497
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-4 text-sm font-semibold uppercase text-muted-foreground", children: t("customers.deals.detail.formTitle", "Deal settings") }),
|
|
498
|
+
/* @__PURE__ */ jsx(
|
|
499
|
+
DealForm,
|
|
500
|
+
{
|
|
501
|
+
mode: "edit",
|
|
502
|
+
initialValues: {
|
|
503
|
+
id: data.deal.id,
|
|
504
|
+
title: data.deal.title ?? "",
|
|
505
|
+
status: data.deal.status ?? "",
|
|
506
|
+
pipelineStage: data.deal.pipelineStage ?? "",
|
|
507
|
+
pipelineId: data.deal.pipelineId ?? "",
|
|
508
|
+
pipelineStageId: data.deal.pipelineStageId ?? "",
|
|
509
|
+
valueAmount: data.deal.valueAmount ? Number(data.deal.valueAmount) : null,
|
|
510
|
+
valueCurrency: data.deal.valueCurrency ?? void 0,
|
|
511
|
+
probability: data.deal.probability ?? null,
|
|
512
|
+
expectedCloseAt: data.deal.expectedCloseAt ?? null,
|
|
513
|
+
description: data.deal.description ?? "",
|
|
514
|
+
personIds: data.people.map((person) => person.id),
|
|
515
|
+
companyIds: data.companies.map((company) => company.id),
|
|
516
|
+
people: data.people.map((person) => ({ id: person.id, label: person.label })),
|
|
517
|
+
companies: data.companies.map((company) => ({ id: company.id, label: company.label })),
|
|
518
|
+
...Object.fromEntries(
|
|
519
|
+
Object.entries(data.customFields).filter(([key]) => key.startsWith("cf_")).map(([key, value]) => [key, value])
|
|
520
|
+
)
|
|
530
521
|
},
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
522
|
+
onSubmit: handleFormSubmit,
|
|
523
|
+
onCancel: () => setReloadToken((token) => token + 1),
|
|
524
|
+
onDelete: handleDelete,
|
|
525
|
+
isSubmitting: isSaving || isDeleting
|
|
526
|
+
},
|
|
527
|
+
data.deal.updatedAt
|
|
528
|
+
)
|
|
529
|
+
]
|
|
530
|
+
}
|
|
531
|
+
) })
|
|
537
532
|
] })
|
|
538
|
-
] }),
|
|
533
|
+
] }) }),
|
|
539
534
|
ConfirmDialogElement
|
|
540
535
|
] });
|
|
541
536
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/customers/backend/customers/deals/%5Bid%5D/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Pencil, MousePointerClick } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { VersionHistoryAction } from '@open-mercato/ui/backend/version-history'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { NotesSection, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { ActivitiesSection } from '../../../../components/detail/ActivitiesSection'\nimport { DealForm, type DealFormSubmitPayload } from '../../../../components/detail/DealForm'\nimport { useCustomerDictionary } from '../../../../components/detail/hooks/useCustomerDictionary'\nimport type { CustomerDictionaryMap } from '../../../../lib/dictionaries'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { renderDictionaryColor, renderDictionaryIcon } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ICON_SUGGESTIONS } from '../../../../lib/dictionaries'\nimport { createCustomerNotesAdapter } from '../../../../components/detail/notesAdapter'\nimport { readMarkdownPreferenceCookie, writeMarkdownPreferenceCookie } from '../../../../lib/markdownPreference'\n\ntype DealAssociation = {\n id: string\n label: string\n subtitle: string | null\n kind: 'person' | 'company'\n}\n\ntype DealDetailPayload = {\n deal: {\n id: string\n title: string\n description: string | null\n status: string | null\n pipelineStage: string | null\n pipelineId: string | null\n pipelineStageId: string | null\n valueAmount: string | null\n valueCurrency: string | null\n probability: number | null\n expectedCloseAt: string | null\n ownerUserId: string | null\n source: string | null\n organizationId: string | null\n tenantId: string | null\n createdAt: string\n updatedAt: string\n }\n people: DealAssociation[]\n companies: DealAssociation[]\n customFields: Record<string, unknown>\n viewer?: {\n userId: string | null\n name?: string | null\n email?: string | null\n } | null\n}\n\nconst CRUD_FOCUSABLE_SELECTOR =\n '[data-crud-focus-target], input:not([type=\"hidden\"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n\nfunction formatCurrency(amount: string | null, currency: string | null): string | null {\n if (!amount) return null\n const value = Number(amount)\n if (!Number.isFinite(value)) return currency ? `${amount} ${currency}` : amount\n if (!currency) return value.toLocaleString()\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${value.toLocaleString()} ${currency}`\n }\n}\n\nfunction formatDate(value: string | null, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })\n}\n\nfunction resolveDictionaryLabel(\n value: string | null | undefined,\n map: CustomerDictionaryMap | null | undefined,\n): string | null {\n if (!value) return null\n const entry = map?.[value]\n if (entry && entry.label && entry.label.length) return entry.label\n return value\n}\n\nexport default function DealDetailPage({ params }: { params?: { id?: string } }) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n const notesAdapter = React.useMemo(() => createCustomerNotesAdapter(detailTranslator), [detailTranslator])\n const router = useRouter()\n const id = params?.id ?? ''\n const scopeVersion = useOrganizationScopeVersion()\n const statusDictionaryQuery = useCustomerDictionary('deal-statuses', scopeVersion)\n const pipelineDictionaryQuery = useCustomerDictionary('pipeline-stages', scopeVersion)\n const statusDictionaryMap = statusDictionaryQuery.data?.map ?? null\n const pipelineDictionaryMap = pipelineDictionaryQuery.data?.map ?? null\n const [data, setData] = React.useState<DealDetailPayload | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isSaving, setIsSaving] = React.useState(false)\n const [isDeleting, setIsDeleting] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [activeTab, setActiveTab] = React.useState<'notes' | 'activities'>('notes')\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const handleNotesLoadingChange = React.useCallback(() => {}, [])\n const handleActivitiesLoadingChange = React.useCallback(() => {}, [])\n const focusDealField = React.useCallback(\n (fieldId: 'title' | 'personIds' | 'companyIds') => {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n const focusOnce = () => {\n const container = document.querySelector<HTMLElement>(`[data-crud-field-id=\"${fieldId}\"]`)\n if (!container) return false\n const target =\n container.querySelector<HTMLElement>(CRUD_FOCUSABLE_SELECTOR) ?? container\n if (!target || typeof target.focus !== 'function') return false\n if (typeof container.scrollIntoView === 'function') {\n container.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n target.focus()\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n try {\n target.select()\n } catch {}\n }\n return true\n }\n\n const schedule = () => {\n const focused = focusOnce()\n if (focused) return\n window.setTimeout(() => {\n focusOnce()\n }, 60)\n }\n\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(schedule)\n } else {\n schedule()\n }\n },\n [],\n )\n const dealSettingsRef = React.useRef<HTMLDivElement | null>(null)\n const scrollToDealSettings = React.useCallback(() => {\n if (typeof window === 'undefined') return\n if (dealSettingsRef.current && typeof dealSettingsRef.current.scrollIntoView === 'function') {\n dealSettingsRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })\n }\n window.setTimeout(() => {\n focusDealField('title')\n }, 160)\n }, [focusDealField])\n\n React.useEffect(() => {\n if (!id) {\n setError(t('customers.deals.detail.missingId', 'Deal id is required.'))\n setIsLoading(false)\n return\n }\n let cancelled = false\n async function loadDeal() {\n setIsLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<DealDetailPayload>(\n `/api/customers/deals/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.deals.detail.loadError', 'Failed to load deal.') },\n )\n if (cancelled) return\n setData(payload as DealDetailPayload)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.loadError', 'Failed to load deal.')\n setError(message)\n setData(null)\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n loadDeal().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [id, reloadToken, t])\n\n const handleFormSubmit = React.useCallback(\n async ({ base, custom }: DealFormSubmitPayload) => {\n if (!data || isSaving) return\n setIsSaving(true)\n try {\n const payload: Record<string, unknown> = {\n id: data.deal.id,\n title: base.title,\n status: base.status ?? undefined,\n pipelineStage: base.pipelineStage ?? undefined,\n pipelineId: base.pipelineId ?? undefined,\n pipelineStageId: base.pipelineStageId ?? undefined,\n valueAmount: typeof base.valueAmount === 'number' ? base.valueAmount : undefined,\n valueCurrency: base.valueCurrency ?? undefined,\n probability: typeof base.probability === 'number' ? base.probability : undefined,\n expectedCloseAt: base.expectedCloseAt ?? undefined,\n description: base.description ?? undefined,\n personIds: base.personIds && base.personIds.length ? base.personIds : undefined,\n companyIds: base.companyIds && base.companyIds.length ? base.companyIds : undefined,\n }\n if (Object.keys(custom).length) payload.customFields = custom\n\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { errorMessage: t('customers.deals.detail.saveError', 'Failed to update deal.') },\n )\n flash(t('customers.deals.detail.saveSuccess', 'Deal updated.'), 'success')\n setReloadToken((token) => token + 1)\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.saveError', 'Failed to update deal.')\n flash(message, 'error')\n throw err instanceof Error ? err : new Error(message)\n } finally {\n setIsSaving(false)\n }\n },\n [data, isSaving, t],\n )\n\n const handleDelete = React.useCallback(async () => {\n if (!data || isDeleting) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.detail.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsDeleting(true)\n try {\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: data.deal.id }),\n },\n { errorMessage: t('customers.deals.detail.deleteError', 'Failed to delete deal.') },\n )\n flash(t('customers.deals.detail.deleteSuccess', 'Deal deleted.'), 'success')\n router.push('/backend/customers/deals')\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setIsDeleting(false)\n }\n }, [confirm, data, isDeleting, router, t])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n const handleSectionAction = React.useCallback(() => {\n if (!sectionAction || sectionAction.disabled) return\n sectionAction.onClick()\n }, [sectionAction])\n\n const dealOptions = React.useMemo(\n () =>\n data\n ? [\n {\n id: data.deal.id,\n label:\n data.deal.title && data.deal.title.length\n ? data.deal.title\n : t('customers.deals.detail.untitled', 'Untitled deal'),\n },\n ]\n : [],\n [data, t],\n )\n\n const entityOptions = React.useMemo(() => {\n if (!data) return []\n const entries: { id: string; label: string }[] = []\n data.people.forEach((person) => {\n if (!person.id) return\n const suffix = person.subtitle ? ` \u00B7 ${person.subtitle}` : ''\n entries.push({ id: person.id, label: `${person.label}${suffix}` })\n })\n data.companies.forEach((company) => {\n if (!company.id) return\n const suffix = company.subtitle ? ` \u00B7 ${company.subtitle}` : ''\n entries.push({ id: company.id, label: `${company.label}${suffix}` })\n })\n return entries\n }, [data])\n\n const defaultEntityId = React.useMemo(() => {\n if (entityOptions.length) return entityOptions[0].id\n return null\n }, [entityOptions])\n\n const tabs = React.useMemo(\n () => [\n { id: 'notes' as const, label: t('customers.deals.detail.tabs.notes', 'Notes') },\n { id: 'activities' as const, label: t('customers.deals.detail.tabs.activities', 'Activities') },\n ],\n [t],\n )\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-6 w-6\" />\n <span>{t('customers.deals.detail.loading', 'Loading deal\u2026')}</span>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-3 text-muted-foreground\">\n <p>{error || t('customers.deals.detail.notFound', 'Deal not found.')}</p>\n <Button variant=\"outline\" asChild>\n <Link href=\"/backend/customers/deals\">\n {t('customers.deals.detail.backToList', 'Back to deals')}\n </Link>\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n const probabilityLabel = data.deal.probability !== null && data.deal.probability !== undefined\n ? `${data.deal.probability}%`\n : t('customers.deals.detail.noValue', 'Not provided')\n const valueLabel =\n formatCurrency(data.deal.valueAmount, data.deal.valueCurrency) ??\n t('customers.deals.detail.noValue', 'Not provided')\n const expectedCloseLabel = formatDate(data.deal.expectedCloseAt, t('customers.deals.detail.noValue', 'Not provided'))\n const statusLabel =\n resolveDictionaryLabel(data.deal.status, statusDictionaryMap) ??\n t('customers.deals.detail.noStatus', 'No status')\n const statusDictEntry = data.deal.status ? statusDictionaryMap?.[data.deal.status] ?? null : null\n const pipelineLabel = resolveDictionaryLabel(data.deal.pipelineStage, pipelineDictionaryMap)\n const pipelineDictEntry = data.deal.pipelineStage ? pipelineDictionaryMap?.[data.deal.pipelineStage] ?? null : null\n const previewValueAmount = formatCurrency(data.deal.valueAmount, data.deal.valueCurrency)\n const previewProbability = data.deal.probability !== null && data.deal.probability !== undefined\n ? `${data.deal.probability}%`\n : null\n const dealPreviewMetadata: Record<string, string> = {}\n if (previewValueAmount) dealPreviewMetadata[t('customers.deals.detail.fields.value')] = previewValueAmount\n if (previewProbability) dealPreviewMetadata[t('customers.deals.detail.fields.probability')] = previewProbability\n\n const peopleSummaryLabel =\n data.people.length === 1\n ? t('customers.deals.detail.peopleSummaryOne')\n : t('customers.deals.detail.peopleSummaryMany', undefined, { count: data.people.length })\n const companiesSummaryLabel =\n data.companies.length === 1\n ? t('customers.deals.detail.companiesSummaryOne')\n : t('customers.deals.detail.companiesSummaryMany', undefined, { count: data.companies.length })\n\n const viewer = data.viewer ?? null\n\n return (\n <Page>\n <PageBody>Piotr nie jest pizd\u0105, tylko zajebistym go\u015Bciem, kt\u00F3ry robi \u015Bwietn\u0105 robot\u0119 w Mercato i jest super mi\u0142y dla wszystkich dooko\u0142a. Dzi\u0119ki Piotrze za wszystko co robisz! <br/><br/>\n <div className=\"flex flex-col gap-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/customers/deals\"\n backLabel={t('customers.deals.detail.backToList', 'Back to deals')}\n utilityActions={(\n <>\n <SendObjectMessageDialog\n object={{\n entityModule: 'customers',\n entityType: 'deal',\n entityId: data.deal.id,\n sourceEntityType: 'customers.deal',\n sourceEntityId: data.deal.id,\n previewData: {\n title: data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal'),\n status: data.deal.status ? statusLabel : undefined,\n metadata: Object.keys(dealPreviewMetadata).length > 0 ? dealPreviewMetadata : undefined,\n },\n }}\n viewHref={`/backend/customers/deals/${data.deal.id}`}\n defaultValues={{\n sourceEntityType: 'customers.deal',\n sourceEntityId: data.deal.id,\n }}\n />\n <VersionHistoryAction\n config={{ resourceKind: 'customers.deal', resourceId: data.deal.id }}\n t={t}\n />\n </>\n )}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal')}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 text-muted-foreground hover:text-foreground\"\n onClick={scrollToDealSettings}\n >\n <Pencil className=\"h-4 w-4\" aria-hidden />\n <MousePointerClick className=\"h-4 w-4\" aria-hidden />\n <span>{t('customers.deals.detail.goToSettings', 'Edit deal details')}</span>\n </Button>\n </div>\n }\n subtitle={t('customers.deals.detail.summary', undefined, {\n status: statusLabel,\n pipeline: pipelineLabel ?? t('customers.deals.detail.noPipeline', 'No pipeline'),\n })}\n onDelete={handleDelete}\n isDeleting={isDeleting}\n deleteLabel={t('ui.actions.delete', 'Delete')}\n />\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]\">\n <div className=\"space-y-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.highlights', 'Highlights')}\n </h2>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.value', 'Deal value')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{valueLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.probability', 'Probability')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{probabilityLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.status', 'Status')}\n </p>\n <p className=\"text-base text-foreground flex items-center gap-2\">\n {statusDictEntry?.color ? renderDictionaryColor(statusDictEntry.color) : null}\n {statusDictEntry?.icon ? renderDictionaryIcon(statusDictEntry.icon) : null}\n {statusLabel}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.pipeline', 'Pipeline stage')}\n </p>\n <p className=\"text-base text-foreground flex items-center gap-2\">\n {pipelineDictEntry?.color ? renderDictionaryColor(pipelineDictEntry.color) : null}\n {pipelineDictEntry?.icon ? renderDictionaryIcon(pipelineDictEntry.icon) : null}\n {pipelineLabel ?? t('customers.deals.detail.noValue', 'Not provided')}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.expectedClose', 'Expected close')}\n </p>\n <p className=\"text-base text-foreground\">{expectedCloseLabel}</p>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex gap-2\">\n {tabs.map((tab) => (\n <Button\n key={tab.id}\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setActiveTab(tab.id)}\n className={`h-auto rounded-none border-b-2 px-0 py-1 ${\n activeTab === tab.id\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent'\n }`}\n >\n {tab.label}\n </Button>\n ))}\n </div>\n {sectionAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={sectionAction.disabled}\n onClick={handleSectionAction}\n >\n {sectionAction.icon ?? null}\n {sectionAction.label}\n </Button>\n ) : null}\n </div>\n {activeTab === 'notes' ? (\n <NotesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n emptyLabel={t('customers.deals.detail.notesEmpty', 'No notes yet.')}\n viewerUserId={viewer?.userId ?? null}\n viewerName={viewer?.name ?? null}\n viewerEmail={viewer?.email ?? null}\n addActionLabel={t('customers.deals.detail.notesAdd', 'Add note')}\n emptyState={{\n title: t('customers.deals.detail.notesEmptyTitle', 'Keep everyone in the loop'),\n actionLabel: t('customers.deals.detail.notesEmptyAction', 'Add a note'),\n }}\n onActionChange={setSectionAction}\n translator={detailTranslator}\n onLoadingChange={handleNotesLoadingChange}\n dataAdapter={notesAdapter}\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n iconSuggestions={ICON_SUGGESTIONS}\n readMarkdownPreference={readMarkdownPreferenceCookie}\n writeMarkdownPreference={writeMarkdownPreferenceCookie}\n />\n ) : null}\n {activeTab === 'activities' ? (\n <ActivitiesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n defaultEntityId={defaultEntityId ?? undefined}\n addActionLabel={t('customers.deals.detail.activitiesAdd', 'Log activity')}\n emptyState={{\n title: t('customers.deals.detail.activitiesEmptyTitle', 'No activities yet'),\n actionLabel: t('customers.deals.detail.activitiesEmptyAction', 'Add an activity'),\n }}\n onActionChange={setSectionAction}\n onLoadingChange={handleActivitiesLoadingChange}\n />\n ) : null}\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.peopleSection', 'People')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {peopleSummaryLabel}\n </p>\n </div>\n {data.people.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.people.map((person) => (\n <li key={person.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/people-v2/${encodeURIComponent(person.id)}`} className=\"font-medium text-foreground hover:underline\">\n {person.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {person.subtitle ?? t('customers.deals.detail.peopleNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noPeople', 'No people linked to this deal yet.')}\n </p>\n )}\n </div>\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.companiesSection', 'Companies')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {companiesSummaryLabel}\n </p>\n </div>\n {data.companies.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.companies.map((company) => (\n <li key={company.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/companies-v2/${encodeURIComponent(company.id)}`} className=\"font-medium text-foreground hover:underline\">\n {company.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {company.subtitle ?? t('customers.deals.detail.companiesNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noCompanies', 'No companies linked to this deal yet.')}\n </p>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-6\">\n <div\n ref={dealSettingsRef}\n id=\"deal-settings\"\n className=\"rounded-lg border bg-card p-4\"\n >\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.formTitle', 'Deal settings')}\n </h2>\n <DealForm\n key={data.deal.updatedAt}\n mode=\"edit\"\n initialValues={{\n id: data.deal.id,\n title: data.deal.title ?? '',\n status: data.deal.status ?? '',\n pipelineStage: data.deal.pipelineStage ?? '',\n pipelineId: data.deal.pipelineId ?? '',\n pipelineStageId: data.deal.pipelineStageId ?? '',\n valueAmount: data.deal.valueAmount ? Number(data.deal.valueAmount) : null,\n valueCurrency: data.deal.valueCurrency ?? undefined,\n probability: data.deal.probability ?? null,\n expectedCloseAt: data.deal.expectedCloseAt ?? null,\n description: data.deal.description ?? '',\n personIds: data.people.map((person) => person.id),\n companyIds: data.companies.map((company) => company.id),\n people: data.people.map((person) => ({ id: person.id, label: person.label })),\n companies: data.companies.map((company) => ({ id: company.id, label: company.label })),\n ...Object.fromEntries(\n Object.entries(data.customFields)\n .filter(([key]) => key.startsWith('cf_'))\n .map(([key, value]) => [key, value]),\n ),\n }}\n onSubmit={handleFormSubmit}\n onCancel={() => setReloadToken((token) => token + 1)}\n onDelete={handleDelete}\n isSubmitting={isSaving || isDeleting}\n />\n </div>\n </div>\n </div>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Pencil, MousePointerClick } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { VersionHistoryAction } from '@open-mercato/ui/backend/version-history'\nimport { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { NotesSection, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { ActivitiesSection } from '../../../../components/detail/ActivitiesSection'\nimport { DealForm, type DealFormSubmitPayload } from '../../../../components/detail/DealForm'\nimport { useCustomerDictionary } from '../../../../components/detail/hooks/useCustomerDictionary'\nimport type { CustomerDictionaryMap } from '../../../../lib/dictionaries'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { renderDictionaryColor, renderDictionaryIcon } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'\nimport { ICON_SUGGESTIONS } from '../../../../lib/dictionaries'\nimport { createCustomerNotesAdapter } from '../../../../components/detail/notesAdapter'\nimport { readMarkdownPreferenceCookie, writeMarkdownPreferenceCookie } from '../../../../lib/markdownPreference'\n\ntype DealAssociation = {\n id: string\n label: string\n subtitle: string | null\n kind: 'person' | 'company'\n}\n\ntype DealDetailPayload = {\n deal: {\n id: string\n title: string\n description: string | null\n status: string | null\n pipelineStage: string | null\n pipelineId: string | null\n pipelineStageId: string | null\n valueAmount: string | null\n valueCurrency: string | null\n probability: number | null\n expectedCloseAt: string | null\n ownerUserId: string | null\n source: string | null\n organizationId: string | null\n tenantId: string | null\n createdAt: string\n updatedAt: string\n }\n people: DealAssociation[]\n companies: DealAssociation[]\n customFields: Record<string, unknown>\n viewer?: {\n userId: string | null\n name?: string | null\n email?: string | null\n } | null\n}\n\nconst CRUD_FOCUSABLE_SELECTOR =\n '[data-crud-focus-target], input:not([type=\"hidden\"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n\nfunction formatCurrency(amount: string | null, currency: string | null): string | null {\n if (!amount) return null\n const value = Number(amount)\n if (!Number.isFinite(value)) return currency ? `${amount} ${currency}` : amount\n if (!currency) return value.toLocaleString()\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${value.toLocaleString()} ${currency}`\n }\n}\n\nfunction formatDate(value: string | null, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })\n}\n\nfunction resolveDictionaryLabel(\n value: string | null | undefined,\n map: CustomerDictionaryMap | null | undefined,\n): string | null {\n if (!value) return null\n const entry = map?.[value]\n if (entry && entry.label && entry.label.length) return entry.label\n return value\n}\n\nexport default function DealDetailPage({ params }: { params?: { id?: string } }) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n const notesAdapter = React.useMemo(() => createCustomerNotesAdapter(detailTranslator), [detailTranslator])\n const router = useRouter()\n const id = params?.id ?? ''\n const scopeVersion = useOrganizationScopeVersion()\n const statusDictionaryQuery = useCustomerDictionary('deal-statuses', scopeVersion)\n const pipelineDictionaryQuery = useCustomerDictionary('pipeline-stages', scopeVersion)\n const statusDictionaryMap = statusDictionaryQuery.data?.map ?? null\n const pipelineDictionaryMap = pipelineDictionaryQuery.data?.map ?? null\n const [data, setData] = React.useState<DealDetailPayload | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isSaving, setIsSaving] = React.useState(false)\n const [isDeleting, setIsDeleting] = React.useState(false)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [activeTab, setActiveTab] = React.useState<'notes' | 'activities'>('notes')\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const handleNotesLoadingChange = React.useCallback(() => {}, [])\n const handleActivitiesLoadingChange = React.useCallback(() => {}, [])\n const focusDealField = React.useCallback(\n (fieldId: 'title' | 'personIds' | 'companyIds') => {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n const focusOnce = () => {\n const container = document.querySelector<HTMLElement>(`[data-crud-field-id=\"${fieldId}\"]`)\n if (!container) return false\n const target =\n container.querySelector<HTMLElement>(CRUD_FOCUSABLE_SELECTOR) ?? container\n if (!target || typeof target.focus !== 'function') return false\n if (typeof container.scrollIntoView === 'function') {\n container.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n target.focus()\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n try {\n target.select()\n } catch {}\n }\n return true\n }\n\n const schedule = () => {\n const focused = focusOnce()\n if (focused) return\n window.setTimeout(() => {\n focusOnce()\n }, 60)\n }\n\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(schedule)\n } else {\n schedule()\n }\n },\n [],\n )\n const dealSettingsRef = React.useRef<HTMLDivElement | null>(null)\n const scrollToDealSettings = React.useCallback(() => {\n if (typeof window === 'undefined') return\n if (dealSettingsRef.current && typeof dealSettingsRef.current.scrollIntoView === 'function') {\n dealSettingsRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })\n }\n window.setTimeout(() => {\n focusDealField('title')\n }, 160)\n }, [focusDealField])\n\n React.useEffect(() => {\n if (!id) {\n setError(t('customers.deals.detail.missingId', 'Deal id is required.'))\n setIsLoading(false)\n return\n }\n let cancelled = false\n async function loadDeal() {\n setIsLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<DealDetailPayload>(\n `/api/customers/deals/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.deals.detail.loadError', 'Failed to load deal.') },\n )\n if (cancelled) return\n setData(payload as DealDetailPayload)\n } catch (err) {\n if (cancelled) return\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.loadError', 'Failed to load deal.')\n setError(message)\n setData(null)\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n loadDeal().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [id, reloadToken, t])\n\n const handleFormSubmit = React.useCallback(\n async ({ base, custom }: DealFormSubmitPayload) => {\n if (!data || isSaving) return\n setIsSaving(true)\n try {\n const payload: Record<string, unknown> = {\n id: data.deal.id,\n title: base.title,\n status: base.status ?? undefined,\n pipelineStage: base.pipelineStage ?? undefined,\n pipelineId: base.pipelineId ?? undefined,\n pipelineStageId: base.pipelineStageId ?? undefined,\n valueAmount: typeof base.valueAmount === 'number' ? base.valueAmount : undefined,\n valueCurrency: base.valueCurrency ?? undefined,\n probability: typeof base.probability === 'number' ? base.probability : undefined,\n expectedCloseAt: base.expectedCloseAt ?? undefined,\n description: base.description ?? undefined,\n personIds: base.personIds && base.personIds.length ? base.personIds : undefined,\n companyIds: base.companyIds && base.companyIds.length ? base.companyIds : undefined,\n }\n if (Object.keys(custom).length) payload.customFields = custom\n\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { errorMessage: t('customers.deals.detail.saveError', 'Failed to update deal.') },\n )\n flash(t('customers.deals.detail.saveSuccess', 'Deal updated.'), 'success')\n setReloadToken((token) => token + 1)\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.saveError', 'Failed to update deal.')\n flash(message, 'error')\n throw err instanceof Error ? err : new Error(message)\n } finally {\n setIsSaving(false)\n }\n },\n [data, isSaving, t],\n )\n\n const handleDelete = React.useCallback(async () => {\n if (!data || isDeleting) return\n const confirmed = await confirm({\n title: t(\n 'customers.deals.detail.deleteConfirm',\n 'Delete this deal? This action cannot be undone.',\n ),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsDeleting(true)\n try {\n await apiCallOrThrow(\n '/api/customers/deals',\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: data.deal.id }),\n },\n { errorMessage: t('customers.deals.detail.deleteError', 'Failed to delete deal.') },\n )\n flash(t('customers.deals.detail.deleteSuccess', 'Deal deleted.'), 'success')\n router.push('/backend/customers/deals')\n } catch (err) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t('customers.deals.detail.deleteError', 'Failed to delete deal.')\n flash(message, 'error')\n } finally {\n setIsDeleting(false)\n }\n }, [confirm, data, isDeleting, router, t])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n const handleSectionAction = React.useCallback(() => {\n if (!sectionAction || sectionAction.disabled) return\n sectionAction.onClick()\n }, [sectionAction])\n\n const dealOptions = React.useMemo(\n () =>\n data\n ? [\n {\n id: data.deal.id,\n label:\n data.deal.title && data.deal.title.length\n ? data.deal.title\n : t('customers.deals.detail.untitled', 'Untitled deal'),\n },\n ]\n : [],\n [data, t],\n )\n\n const entityOptions = React.useMemo(() => {\n if (!data) return []\n const entries: { id: string; label: string }[] = []\n data.people.forEach((person) => {\n if (!person.id) return\n const suffix = person.subtitle ? ` \u00B7 ${person.subtitle}` : ''\n entries.push({ id: person.id, label: `${person.label}${suffix}` })\n })\n data.companies.forEach((company) => {\n if (!company.id) return\n const suffix = company.subtitle ? ` \u00B7 ${company.subtitle}` : ''\n entries.push({ id: company.id, label: `${company.label}${suffix}` })\n })\n return entries\n }, [data])\n\n const defaultEntityId = React.useMemo(() => {\n if (entityOptions.length) return entityOptions[0].id\n return null\n }, [entityOptions])\n\n const tabs = React.useMemo(\n () => [\n { id: 'notes' as const, label: t('customers.deals.detail.tabs.notes', 'Notes') },\n { id: 'activities' as const, label: t('customers.deals.detail.tabs.activities', 'Activities') },\n ],\n [t],\n )\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-6 w-6\" />\n <span>{t('customers.deals.detail.loading', 'Loading deal\u2026')}</span>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-3 text-muted-foreground\">\n <p>{error || t('customers.deals.detail.notFound', 'Deal not found.')}</p>\n <Button variant=\"outline\" asChild>\n <Link href=\"/backend/customers/deals\">\n {t('customers.deals.detail.backToList', 'Back to deals')}\n </Link>\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n const probabilityLabel = data.deal.probability !== null && data.deal.probability !== undefined\n ? `${data.deal.probability}%`\n : t('customers.deals.detail.noValue', 'Not provided')\n const valueLabel =\n formatCurrency(data.deal.valueAmount, data.deal.valueCurrency) ??\n t('customers.deals.detail.noValue', 'Not provided')\n const expectedCloseLabel = formatDate(data.deal.expectedCloseAt, t('customers.deals.detail.noValue', 'Not provided'))\n const statusLabel =\n resolveDictionaryLabel(data.deal.status, statusDictionaryMap) ??\n t('customers.deals.detail.noStatus', 'No status')\n const statusDictEntry = data.deal.status ? statusDictionaryMap?.[data.deal.status] ?? null : null\n const pipelineLabel = resolveDictionaryLabel(data.deal.pipelineStage, pipelineDictionaryMap)\n const pipelineDictEntry = data.deal.pipelineStage ? pipelineDictionaryMap?.[data.deal.pipelineStage] ?? null : null\n const previewValueAmount = formatCurrency(data.deal.valueAmount, data.deal.valueCurrency)\n const previewProbability = data.deal.probability !== null && data.deal.probability !== undefined\n ? `${data.deal.probability}%`\n : null\n const dealPreviewMetadata: Record<string, string> = {}\n if (previewValueAmount) dealPreviewMetadata[t('customers.deals.detail.fields.value')] = previewValueAmount\n if (previewProbability) dealPreviewMetadata[t('customers.deals.detail.fields.probability')] = previewProbability\n\n const peopleSummaryLabel =\n data.people.length === 1\n ? t('customers.deals.detail.peopleSummaryOne')\n : t('customers.deals.detail.peopleSummaryMany', undefined, { count: data.people.length })\n const companiesSummaryLabel =\n data.companies.length === 1\n ? t('customers.deals.detail.companiesSummaryOne')\n : t('customers.deals.detail.companiesSummaryMany', undefined, { count: data.companies.length })\n\n const viewer = data.viewer ?? null\n\n return (\n <Page>\n <PageBody>\n <div className=\"flex flex-col gap-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/customers/deals\"\n backLabel={t('customers.deals.detail.backToList', 'Back to deals')}\n utilityActions={(\n <>\n <SendObjectMessageDialog\n object={{\n entityModule: 'customers',\n entityType: 'deal',\n entityId: data.deal.id,\n sourceEntityType: 'customers.deal',\n sourceEntityId: data.deal.id,\n previewData: {\n title: data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal'),\n status: data.deal.status ? statusLabel : undefined,\n metadata: Object.keys(dealPreviewMetadata).length > 0 ? dealPreviewMetadata : undefined,\n },\n }}\n viewHref={`/backend/customers/deals/${data.deal.id}`}\n defaultValues={{\n sourceEntityType: 'customers.deal',\n sourceEntityId: data.deal.id,\n }}\n />\n <VersionHistoryAction\n config={{ resourceKind: 'customers.deal', resourceId: data.deal.id }}\n t={t}\n />\n </>\n )}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal')}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 text-muted-foreground hover:text-foreground\"\n onClick={scrollToDealSettings}\n >\n <Pencil className=\"h-4 w-4\" aria-hidden />\n <MousePointerClick className=\"h-4 w-4\" aria-hidden />\n <span>{t('customers.deals.detail.goToSettings', 'Edit deal details')}</span>\n </Button>\n </div>\n }\n subtitle={t('customers.deals.detail.summary', undefined, {\n status: statusLabel,\n pipeline: pipelineLabel ?? t('customers.deals.detail.noPipeline', 'No pipeline'),\n })}\n onDelete={handleDelete}\n isDeleting={isDeleting}\n deleteLabel={t('ui.actions.delete', 'Delete')}\n />\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr),minmax(0,1.1fr)]\">\n <div className=\"space-y-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.highlights', 'Highlights')}\n </h2>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.value', 'Deal value')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{valueLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.probability', 'Probability')}\n </p>\n <p className=\"text-base font-semibold text-foreground\">{probabilityLabel}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.status', 'Status')}\n </p>\n <p className=\"text-base text-foreground flex items-center gap-2\">\n {statusDictEntry?.color ? renderDictionaryColor(statusDictEntry.color) : null}\n {statusDictEntry?.icon ? renderDictionaryIcon(statusDictEntry.icon) : null}\n {statusLabel}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.pipeline', 'Pipeline stage')}\n </p>\n <p className=\"text-base text-foreground flex items-center gap-2\">\n {pipelineDictEntry?.color ? renderDictionaryColor(pipelineDictEntry.color) : null}\n {pipelineDictEntry?.icon ? renderDictionaryIcon(pipelineDictEntry.icon) : null}\n {pipelineLabel ?? t('customers.deals.detail.noValue', 'Not provided')}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase text-muted-foreground\">\n {t('customers.deals.detail.fields.expectedClose', 'Expected close')}\n </p>\n <p className=\"text-base text-foreground\">{expectedCloseLabel}</p>\n </div>\n </div>\n </div>\n\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex gap-2\">\n {tabs.map((tab) => (\n <Button\n key={tab.id}\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setActiveTab(tab.id)}\n className={`h-auto rounded-none border-b-2 px-0 py-1 ${\n activeTab === tab.id\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent'\n }`}\n >\n {tab.label}\n </Button>\n ))}\n </div>\n {sectionAction ? (\n <Button\n type=\"button\"\n size=\"sm\"\n disabled={sectionAction.disabled}\n onClick={handleSectionAction}\n >\n {sectionAction.icon ?? null}\n {sectionAction.label}\n </Button>\n ) : null}\n </div>\n {activeTab === 'notes' ? (\n <NotesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n emptyLabel={t('customers.deals.detail.notesEmpty', 'No notes yet.')}\n viewerUserId={viewer?.userId ?? null}\n viewerName={viewer?.name ?? null}\n viewerEmail={viewer?.email ?? null}\n addActionLabel={t('customers.deals.detail.notesAdd', 'Add note')}\n emptyState={{\n title: t('customers.deals.detail.notesEmptyTitle', 'Keep everyone in the loop'),\n actionLabel: t('customers.deals.detail.notesEmptyAction', 'Add a note'),\n }}\n onActionChange={setSectionAction}\n translator={detailTranslator}\n onLoadingChange={handleNotesLoadingChange}\n dataAdapter={notesAdapter}\n renderIcon={renderDictionaryIcon}\n renderColor={renderDictionaryColor}\n iconSuggestions={ICON_SUGGESTIONS}\n readMarkdownPreference={readMarkdownPreferenceCookie}\n writeMarkdownPreference={writeMarkdownPreferenceCookie}\n />\n ) : null}\n {activeTab === 'activities' ? (\n <ActivitiesSection\n entityId={null}\n dealId={data.deal.id}\n dealOptions={dealOptions}\n entityOptions={entityOptions}\n defaultEntityId={defaultEntityId ?? undefined}\n addActionLabel={t('customers.deals.detail.activitiesAdd', 'Log activity')}\n emptyState={{\n title: t('customers.deals.detail.activitiesEmptyTitle', 'No activities yet'),\n actionLabel: t('customers.deals.detail.activitiesEmptyAction', 'Add an activity'),\n }}\n onActionChange={setSectionAction}\n onLoadingChange={handleActivitiesLoadingChange}\n />\n ) : null}\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.peopleSection', 'People')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {peopleSummaryLabel}\n </p>\n </div>\n {data.people.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.people.map((person) => (\n <li key={person.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/people-v2/${encodeURIComponent(person.id)}`} className=\"font-medium text-foreground hover:underline\">\n {person.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {person.subtitle ?? t('customers.deals.detail.peopleNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noPeople', 'No people linked to this deal yet.')}\n </p>\n )}\n </div>\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"mb-3 space-y-1\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {t('customers.deals.detail.companiesSection', 'Companies')}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {companiesSummaryLabel}\n </p>\n </div>\n {data.companies.length ? (\n <ul className=\"space-y-2 text-sm\">\n {data.companies.map((company) => (\n <li key={company.id} className=\"flex flex-col gap-1\">\n <Link href={`/backend/customers/companies-v2/${encodeURIComponent(company.id)}`} className=\"font-medium text-foreground hover:underline\">\n {company.label}\n </Link>\n <span className=\"text-xs text-muted-foreground\">\n {company.subtitle ?? t('customers.deals.detail.companiesNoDetails', 'No additional details')}\n </span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('customers.deals.detail.noCompanies', 'No companies linked to this deal yet.')}\n </p>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-6\">\n <div\n ref={dealSettingsRef}\n id=\"deal-settings\"\n className=\"rounded-lg border bg-card p-4\"\n >\n <h2 className=\"mb-4 text-sm font-semibold uppercase text-muted-foreground\">\n {t('customers.deals.detail.formTitle', 'Deal settings')}\n </h2>\n <DealForm\n key={data.deal.updatedAt}\n mode=\"edit\"\n initialValues={{\n id: data.deal.id,\n title: data.deal.title ?? '',\n status: data.deal.status ?? '',\n pipelineStage: data.deal.pipelineStage ?? '',\n pipelineId: data.deal.pipelineId ?? '',\n pipelineStageId: data.deal.pipelineStageId ?? '',\n valueAmount: data.deal.valueAmount ? Number(data.deal.valueAmount) : null,\n valueCurrency: data.deal.valueCurrency ?? undefined,\n probability: data.deal.probability ?? null,\n expectedCloseAt: data.deal.expectedCloseAt ?? null,\n description: data.deal.description ?? '',\n personIds: data.people.map((person) => person.id),\n companyIds: data.companies.map((company) => company.id),\n people: data.people.map((person) => ({ id: person.id, label: person.label })),\n companies: data.companies.map((company) => ({ id: company.id, label: company.label })),\n ...Object.fromEntries(\n Object.entries(data.customFields)\n .filter(([key]) => key.startsWith('cf_'))\n .map(([key, value]) => [key, value]),\n ),\n }}\n onSubmit={handleFormSubmit}\n onCancel={() => setReloadToken((token) => token + 1)}\n onDelete={handleDelete}\n isSubmitting={isSaving || isDeleting}\n />\n </div>\n </div>\n </div>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.4.11-develop.
|
|
3
|
+
"version": "0.4.11-develop.1447.556dc05740",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -230,10 +230,10 @@
|
|
|
230
230
|
"ts-pattern": "^5.0.0"
|
|
231
231
|
},
|
|
232
232
|
"peerDependencies": {
|
|
233
|
-
"@open-mercato/shared": "0.4.11-develop.
|
|
233
|
+
"@open-mercato/shared": "0.4.11-develop.1447.556dc05740"
|
|
234
234
|
},
|
|
235
235
|
"devDependencies": {
|
|
236
|
-
"@open-mercato/shared": "0.4.11-develop.
|
|
236
|
+
"@open-mercato/shared": "0.4.11-develop.1447.556dc05740",
|
|
237
237
|
"@testing-library/dom": "^10.4.1",
|
|
238
238
|
"@testing-library/jest-dom": "^6.9.1",
|
|
239
239
|
"@testing-library/react": "^16.3.1",
|
|
@@ -401,7 +401,7 @@ export default function DealDetailPage({ params }: { params?: { id?: string } })
|
|
|
401
401
|
|
|
402
402
|
return (
|
|
403
403
|
<Page>
|
|
404
|
-
<PageBody>
|
|
404
|
+
<PageBody>
|
|
405
405
|
<div className="flex flex-col gap-6">
|
|
406
406
|
<FormHeader
|
|
407
407
|
mode="detail"
|