@elevasis/ui 2.17.2 → 2.19.0
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.
- package/dist/api/index.js +2 -2
- package/dist/app/index.js +5 -5
- package/dist/charts/index.js +3 -3
- package/dist/chunk-3JCMO7SD.js +14 -0
- package/dist/{chunk-TP5NMF6K.js → chunk-46Z2VHY3.js} +4 -4
- package/dist/{chunk-FNWWVX5N.js → chunk-5SCVXZPM.js} +358 -188
- package/dist/{chunk-TTP62HWW.js → chunk-BHR7IV72.js} +10 -15
- package/dist/{chunk-MJ6YV2B5.js → chunk-CTTY6FUT.js} +2 -2
- package/dist/{chunk-P3TFNFZS.js → chunk-EUWBY43Z.js} +2 -2
- package/dist/{chunk-MDO4UCEJ.js → chunk-IBOX2M24.js} +47 -82
- package/dist/{chunk-HH3RNG2O.js → chunk-JEQM67SO.js} +307 -173
- package/dist/{chunk-2TDZBYXI.js → chunk-LR5CRY5A.js} +1 -1
- package/dist/{chunk-JU6UB4YA.js → chunk-LVCJ2H2T.js} +4 -4
- package/dist/{chunk-GRGRBWIO.js → chunk-M7W7CGPL.js} +1 -1
- package/dist/{chunk-34NQLV2W.js → chunk-MJAKU2WA.js} +3 -3
- package/dist/{chunk-OCCZRPER.js → chunk-Q4QJOSVS.js} +1 -1
- package/dist/{chunk-R73EHHPN.js → chunk-Q5HC6ENG.js} +18 -2
- package/dist/{chunk-VDM6DQES.js → chunk-R7OJCNL3.js} +1 -1
- package/dist/{chunk-6RWMRQN5.js → chunk-TIIPYB2Z.js} +1 -1
- package/dist/{chunk-ABUDMATM.js → chunk-TKEKYPZA.js} +6 -6
- package/dist/{chunk-R7GKX4HW.js → chunk-UU6PJ4EJ.js} +192 -82
- package/dist/{chunk-7L42RRHZ.js → chunk-Y7TDUZEH.js} +221 -514
- package/dist/{chunk-7GCWOUFT.js → chunk-YVAXWM3W.js} +73 -121
- package/dist/components/index.d.ts +219 -2810
- package/dist/components/index.js +41 -27
- package/dist/features/crm/index.d.ts +54 -53
- package/dist/features/crm/index.js +11 -11
- package/dist/features/dashboard/index.js +12 -12
- package/dist/features/delivery/index.d.ts +2642 -2605
- package/dist/features/delivery/index.js +11 -11
- package/dist/features/lead-gen/index.d.ts +152 -16
- package/dist/features/lead-gen/index.js +11 -22
- package/dist/features/monitoring/index.js +13 -13
- package/dist/features/monitoring/requests/index.d.ts +38 -27
- package/dist/features/monitoring/requests/index.js +212 -106
- package/dist/features/operations/index.d.ts +9 -26
- package/dist/features/operations/index.js +15 -15
- package/dist/features/settings/index.d.ts +36 -37
- package/dist/features/settings/index.js +12 -12
- package/dist/hooks/delivery/index.d.ts +2712 -2699
- package/dist/hooks/delivery/index.js +2 -2
- package/dist/hooks/index.d.ts +1997 -4627
- package/dist/hooks/index.js +10 -10
- package/dist/hooks/published.d.ts +1997 -4627
- package/dist/hooks/published.js +10 -10
- package/dist/index.d.ts +1124 -3673
- package/dist/index.js +11 -11
- package/dist/layout/index.d.ts +14 -2
- package/dist/layout/index.js +1 -1
- package/dist/provider/index.d.ts +320 -249
- package/dist/provider/index.js +8 -8
- package/dist/provider/published.d.ts +320 -249
- package/dist/provider/published.js +5 -5
- package/dist/sse/index.d.ts +1 -6
- package/dist/theme/index.js +2 -2
- package/dist/types/index.d.ts +1608 -2487
- package/dist/utils/index.d.ts +32 -1
- package/dist/utils/index.js +1 -1
- package/dist/zustand/index.d.ts +4 -8
- package/dist/zustand/index.js +2 -2
- package/package.json +4 -4
- package/dist/chunk-ADSSLKKP.js +0 -10
- /package/dist/{chunk-GCBWGGI6.js → chunk-OD7GWIZS.js} +0 -0
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import { ResourceExecuteDialog } from './chunk-HH3RNG2O.js';
|
|
2
1
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
3
2
|
import { TableSelectionToolbar, SortableHeader } from './chunk-TUMSNGTX.js';
|
|
4
3
|
import { SubshellNavItem } from './chunk-CEWTOKE7.js';
|
|
5
4
|
import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
|
|
6
5
|
import { FilterBar } from './chunk-PDHTXPSF.js';
|
|
7
6
|
import { CustomModal } from './chunk-GBMNCNHX.js';
|
|
8
|
-
import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useList, useListProgress, useListExecutions,
|
|
9
|
-
import { showApiErrorNotification, showSuccessNotification } from './chunk-
|
|
7
|
+
import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useList, useListProgress, useListExecutions, useContacts, useCompanies, useCompanyFacets, useDeleteCompanies, useDeleteContacts } from './chunk-UU6PJ4EJ.js';
|
|
8
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-M7W7CGPL.js';
|
|
10
9
|
import { SubshellContentContainer } from './chunk-RX4UWZZR.js';
|
|
11
|
-
import { PageTitleCaption, CenteredErrorState, StatCard, EmptyState } from './chunk-
|
|
10
|
+
import { PageTitleCaption, CenteredErrorState, StatCard, CardHeader, EmptyState } from './chunk-BHR7IV72.js';
|
|
12
11
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
13
12
|
import { useElevasisServices } from './chunk-IRW7JMQ4.js';
|
|
14
|
-
import { Stack, Paper, Text, Anchor, Group, Title, ActionIcon, Divider, Box, SimpleGrid, Badge, Card, Button, Center, Loader, Alert, Table,
|
|
15
|
-
import { IconLayoutGrid, IconList, IconBuilding, IconAddressBook,
|
|
13
|
+
import { Stack, Paper, Text, Anchor, Group, Title, ActionIcon, Divider, Box, SimpleGrid, Badge, Card, Button, Center, Loader, Alert, Table, TextInput, Checkbox, Pagination, Textarea, Select, SegmentedControl } from '@mantine/core';
|
|
14
|
+
import { IconLayoutGrid, IconList, IconBuilding, IconAddressBook, IconTarget, IconExternalLink, IconX, IconAlertCircle, IconPlayerPlay, IconArrowRight, IconSparkles, IconListDetails, IconPlus, IconSearch, IconAlertTriangle, IconArrowLeft, IconUsers, IconBuildingFactory2 } from '@tabler/icons-react';
|
|
16
15
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
17
16
|
import { Link, useNavigate } from '@tanstack/react-router';
|
|
18
17
|
import { useQueryClient, useMutation } from '@tanstack/react-query';
|
|
19
|
-
import { useState, useMemo } from 'react';
|
|
18
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
20
19
|
|
|
21
20
|
var LeadGenSidebarTop = () => {
|
|
22
21
|
return /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconTarget, label: "Lead Gen" });
|
|
@@ -25,8 +24,7 @@ var LEAD_GEN_ITEMS = [
|
|
|
25
24
|
{ label: "Overview", to: "/lead-gen", icon: IconLayoutGrid, exact: true },
|
|
26
25
|
{ label: "Lists", to: "/lead-gen/lists", icon: IconList, exact: false },
|
|
27
26
|
{ label: "Companies", to: "/lead-gen/companies", icon: IconBuilding, exact: false },
|
|
28
|
-
{ label: "Contacts", to: "/lead-gen/contacts", icon: IconAddressBook, exact: false }
|
|
29
|
-
{ label: "Deliverability", to: "/lead-gen/deliverability", icon: IconMailCheck, exact: false }
|
|
27
|
+
{ label: "Contacts", to: "/lead-gen/contacts", icon: IconAddressBook, exact: false }
|
|
30
28
|
];
|
|
31
29
|
var LeadGenSidebarMiddle = ({ items = LEAD_GEN_ITEMS } = {}) => {
|
|
32
30
|
const { currentPath, navigate } = useRouterContext();
|
|
@@ -66,8 +64,7 @@ var LEAD_GEN_ROUTE_LINKS = [
|
|
|
66
64
|
{ label: "Overview", to: "/lead-gen" },
|
|
67
65
|
{ label: "Lists", to: "/lead-gen/lists" },
|
|
68
66
|
{ label: "Companies", to: "/lead-gen/companies" },
|
|
69
|
-
{ label: "Contacts", to: "/lead-gen/contacts" }
|
|
70
|
-
{ label: "Deliverability", to: "/lead-gen/deliverability" }
|
|
67
|
+
{ label: "Contacts", to: "/lead-gen/contacts" }
|
|
71
68
|
];
|
|
72
69
|
function LeadGenRouteShell({
|
|
73
70
|
title,
|
|
@@ -121,7 +118,10 @@ function formatName(parts, fallback) {
|
|
|
121
118
|
const name = parts.filter(Boolean).join(" ").trim();
|
|
122
119
|
return name || fallback;
|
|
123
120
|
}
|
|
124
|
-
function CompanyDetailModal({
|
|
121
|
+
function CompanyDetailModal({
|
|
122
|
+
company,
|
|
123
|
+
onClose
|
|
124
|
+
}) {
|
|
125
125
|
return /* @__PURE__ */ jsx(CustomModal, { opened: !!company, onClose, size: "xl", children: company ? /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
126
126
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
127
127
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -185,7 +185,10 @@ function CompanyDetailModal({ company, onClose }) {
|
|
|
185
185
|
] })
|
|
186
186
|
] }) : null });
|
|
187
187
|
}
|
|
188
|
-
function ContactDetailModal({
|
|
188
|
+
function ContactDetailModal({
|
|
189
|
+
contact,
|
|
190
|
+
onClose
|
|
191
|
+
}) {
|
|
189
192
|
return /* @__PURE__ */ jsx(CustomModal, { opened: !!contact, onClose, size: "xl", children: contact ? /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
190
193
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
191
194
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -441,23 +444,6 @@ function useDeleteLists() {
|
|
|
441
444
|
}
|
|
442
445
|
});
|
|
443
446
|
}
|
|
444
|
-
var EM_DASH = "\u2014";
|
|
445
|
-
function computeCompletionRatio(populated, personalized) {
|
|
446
|
-
if (populated === 0) return null;
|
|
447
|
-
return personalized / populated;
|
|
448
|
-
}
|
|
449
|
-
function formatPercentage(ratio, fractionDigits = 0) {
|
|
450
|
-
if (ratio == null) return EM_DASH;
|
|
451
|
-
return `${(ratio * 100).toFixed(fractionDigits)}%`;
|
|
452
|
-
}
|
|
453
|
-
function computeCompletionPercentage(populated, personalized) {
|
|
454
|
-
return formatPercentage(computeCompletionRatio(populated, personalized));
|
|
455
|
-
}
|
|
456
|
-
function computeBounceRate(d) {
|
|
457
|
-
const denominator = d.valid + d.risky + d.invalid + d.bounced;
|
|
458
|
-
if (denominator === 0) return EM_DASH;
|
|
459
|
-
return `${(d.bounced / denominator * 100).toFixed(1)}%`;
|
|
460
|
-
}
|
|
461
447
|
function computeBacklog(current, completed) {
|
|
462
448
|
return Math.max(current - completed, 0);
|
|
463
449
|
}
|
|
@@ -545,8 +531,8 @@ function getPrimaryAction({
|
|
|
545
531
|
return {
|
|
546
532
|
title: `Resolve ${formatCountLabel(deliverabilityRiskCount, "deliverability risk")}`,
|
|
547
533
|
detail: "Risky, invalid, or bounced records are the main campaign health issue right now.",
|
|
548
|
-
buttonLabel: "
|
|
549
|
-
buttonTo: "/lead-gen/
|
|
534
|
+
buttonLabel: "Review lists",
|
|
535
|
+
buttonTo: "/lead-gen/lists",
|
|
550
536
|
tone: "orange"
|
|
551
537
|
};
|
|
552
538
|
}
|
|
@@ -576,24 +562,12 @@ function getPrimaryAction({
|
|
|
576
562
|
tone: "gray"
|
|
577
563
|
};
|
|
578
564
|
}
|
|
579
|
-
function CompactPipelineStage({ label, value, ratio }) {
|
|
580
|
-
return /* @__PURE__ */ jsx(Card, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
|
|
581
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", wrap: "nowrap", children: [
|
|
582
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", tt: "uppercase", fw: 600, children: label }),
|
|
583
|
-
/* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "blue", children: formatPercentage(ratio) })
|
|
584
|
-
] }),
|
|
585
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: value }),
|
|
586
|
-
/* @__PURE__ */ jsx(Progress, { value: ratio == null ? 0 : ratio * 100, size: "sm", radius: "xl", color: "blue" })
|
|
587
|
-
] }) });
|
|
588
|
-
}
|
|
589
565
|
function LeadGenOverviewPage() {
|
|
590
566
|
const navigate = useNavigate();
|
|
591
567
|
const telemetryQuery = useListsTelemetry();
|
|
592
568
|
const listsQuery = useLists();
|
|
593
569
|
const data = telemetryQuery.data;
|
|
594
570
|
const listMetaById = new Map((listsQuery.data ?? []).map((list) => [list.id, list]));
|
|
595
|
-
const totalCompanies = data?.reduce((sum, list) => sum + list.totalCompanies, 0) ?? 0;
|
|
596
|
-
const totalContacts = data?.reduce((sum, list) => sum + list.totalContacts, 0) ?? 0;
|
|
597
571
|
const stageTotals = data?.reduce(
|
|
598
572
|
(acc, list) => ({
|
|
599
573
|
populated: acc.populated + list.stageCounts.populated,
|
|
@@ -605,7 +579,7 @@ function LeadGenOverviewPage() {
|
|
|
605
579
|
uploaded: acc.uploaded + list.stageCounts.uploaded
|
|
606
580
|
}),
|
|
607
581
|
{ populated: 0, extracted: 0, qualified: 0, discovered: 0, verified: 0, personalized: 0, uploaded: 0 }
|
|
608
|
-
) ?? {
|
|
582
|
+
) ?? { discovered: 0, verified: 0, personalized: 0, uploaded: 0 };
|
|
609
583
|
const deliverabilityTotals = data?.reduce(
|
|
610
584
|
(acc, list) => ({
|
|
611
585
|
valid: acc.valid + list.deliverability.valid,
|
|
@@ -623,10 +597,10 @@ function LeadGenOverviewPage() {
|
|
|
623
597
|
const deliverabilityRiskCount = deliverabilityTotals.risky + deliverabilityTotals.invalid + deliverabilityTotals.bounced;
|
|
624
598
|
const totalLists = data?.length ?? 0;
|
|
625
599
|
const summaryLine = [
|
|
626
|
-
`${totalLists} ${totalLists === 1 ? "list" : "lists"}
|
|
600
|
+
`${totalLists} total ${totalLists === 1 ? "list" : "lists"}`,
|
|
627
601
|
`${formatCountLabel(uploadBacklog, "contact")} ready for upload`,
|
|
628
602
|
deliverabilityRiskCount === 0 ? "no risks" : `${formatCountLabel(deliverabilityRiskCount, "risk")}`
|
|
629
|
-
].join("
|
|
603
|
+
].join(" | ");
|
|
630
604
|
const primaryAction = getPrimaryAction({
|
|
631
605
|
uploadBacklog,
|
|
632
606
|
personalizationBacklog,
|
|
@@ -635,41 +609,12 @@ function LeadGenOverviewPage() {
|
|
|
635
609
|
activeListCount,
|
|
636
610
|
totalLists
|
|
637
611
|
});
|
|
638
|
-
const pipelineStages = [
|
|
639
|
-
{
|
|
640
|
-
label: "Populated",
|
|
641
|
-
value: stageTotals.populated,
|
|
642
|
-
ratio: totalCompanies === 0 ? null : stageTotals.populated / totalCompanies
|
|
643
|
-
},
|
|
644
|
-
{
|
|
645
|
-
label: "Qualified",
|
|
646
|
-
value: stageTotals.qualified,
|
|
647
|
-
ratio: totalCompanies === 0 ? null : stageTotals.qualified / totalCompanies
|
|
648
|
-
},
|
|
649
|
-
{
|
|
650
|
-
label: "Verified",
|
|
651
|
-
value: stageTotals.verified,
|
|
652
|
-
ratio: totalContacts === 0 ? null : stageTotals.verified / totalContacts
|
|
653
|
-
},
|
|
654
|
-
{
|
|
655
|
-
label: "Personalized",
|
|
656
|
-
value: stageTotals.personalized,
|
|
657
|
-
ratio: totalContacts === 0 ? null : stageTotals.personalized / totalContacts
|
|
658
|
-
},
|
|
659
|
-
{
|
|
660
|
-
label: "Uploaded",
|
|
661
|
-
value: stageTotals.uploaded,
|
|
662
|
-
ratio: totalContacts === 0 ? null : stageTotals.uploaded / totalContacts
|
|
663
|
-
}
|
|
664
|
-
];
|
|
665
612
|
const overviewRows = data?.map((list) => {
|
|
666
613
|
const listMeta = listMetaById.get(list.listId);
|
|
667
|
-
const completionRatio = computeCompletionRatio(list.stageCounts.populated, list.stageCounts.personalized);
|
|
668
614
|
const nextFocus = getNextFocus(list);
|
|
669
615
|
return {
|
|
670
616
|
...list,
|
|
671
617
|
name: listMeta?.name ?? `List ${list.listId.slice(0, 8)}`,
|
|
672
|
-
completionRatio,
|
|
673
618
|
nextFocus,
|
|
674
619
|
status: getOverviewStatus(list)
|
|
675
620
|
};
|
|
@@ -688,28 +633,27 @@ function LeadGenOverviewPage() {
|
|
|
688
633
|
{
|
|
689
634
|
title: "Lead Gen Overview",
|
|
690
635
|
caption: summaryLine,
|
|
691
|
-
rightSection: /* @__PURE__ */
|
|
692
|
-
/* @__PURE__ */ jsx(Button, { component: Link, to: "/lead-gen/lists", size: "sm", variant: "light", children: "Lists" }),
|
|
693
|
-
/* @__PURE__ */ jsx(Button, { component: Link, to: "/lead-gen/deliverability", size: "sm", variant: "light", children: "Deliverability" })
|
|
694
|
-
] })
|
|
636
|
+
rightSection: /* @__PURE__ */ jsx(Button, { component: Link, to: "/lead-gen/lists", size: "xs", variant: "light", children: "Lists" })
|
|
695
637
|
}
|
|
696
638
|
),
|
|
697
639
|
telemetryQuery.isLoading ? /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) }) : telemetryQuery.isError ? /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(CenteredErrorState, { error: telemetryQuery.error, title: "Failed to load list telemetry" }) }) : !data?.length ? /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { h: 300, children: /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), color: "gray", variant: "light", children: "No lists yet." }) }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
698
640
|
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 3 }, children: [
|
|
699
|
-
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconPlayerPlay, value:
|
|
641
|
+
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconPlayerPlay, value: totalLists, label: "Total Lists" }),
|
|
700
642
|
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconArrowRight, value: uploadBacklog, label: "Ready Contacts" }),
|
|
701
643
|
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconAlertCircle, value: deliverabilityRiskCount, label: "At Risk" })
|
|
702
644
|
] }),
|
|
703
645
|
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
704
|
-
/* @__PURE__ */
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
/* @__PURE__ */ jsx(
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
646
|
+
/* @__PURE__ */ jsx(
|
|
647
|
+
CardHeader,
|
|
648
|
+
{
|
|
649
|
+
icon: /* @__PURE__ */ jsx(IconSparkles, { size: 18 }),
|
|
650
|
+
title: "Next Action",
|
|
651
|
+
subtitle: primaryAction.title,
|
|
652
|
+
rightSection: /* @__PURE__ */ jsx(Button, { component: Link, to: primaryAction.buttonTo, size: "xs", variant: "light", children: primaryAction.buttonLabel })
|
|
653
|
+
}
|
|
654
|
+
),
|
|
655
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", maw: 620, children: primaryAction.detail }),
|
|
656
|
+
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md: 2 }, children: [
|
|
713
657
|
/* @__PURE__ */ jsxs(Card, { withBorder: true, p: "sm", children: [
|
|
714
658
|
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", tt: "uppercase", fw: 600, children: "Verification" }),
|
|
715
659
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-end", mt: 6, children: [
|
|
@@ -723,54 +667,25 @@ function LeadGenOverviewPage() {
|
|
|
723
667
|
/* @__PURE__ */ jsx(Title, { order: 4, children: personalizationBacklog }),
|
|
724
668
|
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "ready" })
|
|
725
669
|
] })
|
|
726
|
-
] }),
|
|
727
|
-
/* @__PURE__ */ jsxs(Card, { withBorder: true, p: "sm", children: [
|
|
728
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", tt: "uppercase", fw: 600, children: "Completion" }),
|
|
729
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-end", mt: 6, children: [
|
|
730
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: computeCompletionPercentage(stageTotals.populated, stageTotals.personalized) }),
|
|
731
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "personalized" })
|
|
732
|
-
] })
|
|
733
670
|
] })
|
|
734
671
|
] })
|
|
735
672
|
] }) }),
|
|
736
673
|
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
737
|
-
/* @__PURE__ */
|
|
738
|
-
|
|
739
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: "Pipeline" }),
|
|
740
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Keep the funnel visible without giving every zero state its own section." })
|
|
741
|
-
] }),
|
|
742
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: "blue", children: [
|
|
743
|
-
stageTotals.extracted,
|
|
744
|
-
" extracted \u2022 ",
|
|
745
|
-
stageTotals.discovered,
|
|
746
|
-
" discovered"
|
|
747
|
-
] })
|
|
748
|
-
] }),
|
|
749
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2, xl: 5 }, children: pipelineStages.map((stage) => /* @__PURE__ */ jsx(
|
|
750
|
-
CompactPipelineStage,
|
|
674
|
+
/* @__PURE__ */ jsx(
|
|
675
|
+
CardHeader,
|
|
751
676
|
{
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
)
|
|
758
|
-
] }) }),
|
|
759
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
760
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-end", children: [
|
|
761
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
762
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: "List Snapshot" }),
|
|
763
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Ranked to surface active work first, then the largest unresolved backlogs." })
|
|
764
|
-
] }),
|
|
765
|
-
/* @__PURE__ */ jsx(Button, { component: Link, to: "/lead-gen/lists", size: "sm", variant: "subtle", children: "Open lists" })
|
|
766
|
-
] }),
|
|
677
|
+
icon: /* @__PURE__ */ jsx(IconListDetails, { size: 18 }),
|
|
678
|
+
title: "List Snapshot",
|
|
679
|
+
subtitle: "Ranked to surface active work first, then the largest unresolved backlogs.",
|
|
680
|
+
rightSection: /* @__PURE__ */ jsx(Button, { component: Link, to: "/lead-gen/lists", size: "xs", variant: "subtle", children: "Open lists" })
|
|
681
|
+
}
|
|
682
|
+
),
|
|
767
683
|
/* @__PURE__ */ jsxs(Table, { children: [
|
|
768
684
|
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
769
685
|
/* @__PURE__ */ jsx(Table.Th, { children: "List" }),
|
|
770
686
|
/* @__PURE__ */ jsx(Table.Th, { children: "Companies" }),
|
|
771
687
|
/* @__PURE__ */ jsx(Table.Th, { children: "Contacts" }),
|
|
772
688
|
/* @__PURE__ */ jsx(Table.Th, { children: "Next Focus" }),
|
|
773
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Progress" }),
|
|
774
689
|
/* @__PURE__ */ jsx(Table.Th, { children: "Status" })
|
|
775
690
|
] }) }),
|
|
776
691
|
/* @__PURE__ */ jsx(Table.Tbody, { children: overviewRows.map((list) => /* @__PURE__ */ jsxs(
|
|
@@ -789,25 +704,6 @@ function LeadGenOverviewPage() {
|
|
|
789
704
|
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: list.nextFocus.label }),
|
|
790
705
|
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: list.nextFocus.count == null ? "No outstanding count" : `${list.nextFocus.count} item${list.nextFocus.count === 1 ? "" : "s"} queued` })
|
|
791
706
|
] }) }),
|
|
792
|
-
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", miw: 150, children: [
|
|
793
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", children: [
|
|
794
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", children: formatPercentage(list.completionRatio) }),
|
|
795
|
-
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
796
|
-
list.stageCounts.personalized,
|
|
797
|
-
"/",
|
|
798
|
-
list.stageCounts.populated || 0
|
|
799
|
-
] })
|
|
800
|
-
] }),
|
|
801
|
-
/* @__PURE__ */ jsx(
|
|
802
|
-
Progress,
|
|
803
|
-
{
|
|
804
|
-
value: list.completionRatio == null ? 0 : list.completionRatio * 100,
|
|
805
|
-
size: "sm",
|
|
806
|
-
radius: "xl",
|
|
807
|
-
color: "blue"
|
|
808
|
-
}
|
|
809
|
-
)
|
|
810
|
-
] }) }),
|
|
811
707
|
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: list.status.color, children: list.status.label }) })
|
|
812
708
|
]
|
|
813
709
|
},
|
|
@@ -818,88 +714,6 @@ function LeadGenOverviewPage() {
|
|
|
818
714
|
] })
|
|
819
715
|
] }) }) });
|
|
820
716
|
}
|
|
821
|
-
function LeadGenDeliverabilityPage() {
|
|
822
|
-
const { data, isLoading, error } = useListsTelemetry();
|
|
823
|
-
if (isLoading) {
|
|
824
|
-
return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
825
|
-
/* @__PURE__ */ jsx(
|
|
826
|
-
PageTitleCaption,
|
|
827
|
-
{
|
|
828
|
-
title: "Deliverability",
|
|
829
|
-
caption: "Email validity breakdown and bounce health across lists"
|
|
830
|
-
}
|
|
831
|
-
),
|
|
832
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) })
|
|
833
|
-
] }) }) });
|
|
834
|
-
}
|
|
835
|
-
if (error) {
|
|
836
|
-
return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
837
|
-
/* @__PURE__ */ jsx(
|
|
838
|
-
PageTitleCaption,
|
|
839
|
-
{
|
|
840
|
-
title: "Deliverability",
|
|
841
|
-
caption: "Email validity breakdown and bounce health across lists"
|
|
842
|
-
}
|
|
843
|
-
),
|
|
844
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(CenteredErrorState, { error, title: "Failed to load deliverability data" }) })
|
|
845
|
-
] }) }) });
|
|
846
|
-
}
|
|
847
|
-
if (data?.length === 0) {
|
|
848
|
-
return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
849
|
-
/* @__PURE__ */ jsx(
|
|
850
|
-
PageTitleCaption,
|
|
851
|
-
{
|
|
852
|
-
title: "Deliverability",
|
|
853
|
-
caption: "Email validity breakdown and bounce health across lists"
|
|
854
|
-
}
|
|
855
|
-
),
|
|
856
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { h: 300, children: /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconMailCheck, { size: 16 }), color: "gray", variant: "light", children: "No lists yet. Deliverability will populate once contacts are validated." }) }) })
|
|
857
|
-
] }) }) });
|
|
858
|
-
}
|
|
859
|
-
const lists = data ?? [];
|
|
860
|
-
const totals = lists.reduce(
|
|
861
|
-
(acc, list) => ({
|
|
862
|
-
valid: acc.valid + list.deliverability.valid,
|
|
863
|
-
risky: acc.risky + list.deliverability.risky,
|
|
864
|
-
invalid: acc.invalid + list.deliverability.invalid,
|
|
865
|
-
unknown: acc.unknown + list.deliverability.unknown,
|
|
866
|
-
bounced: acc.bounced + list.deliverability.bounced
|
|
867
|
-
}),
|
|
868
|
-
{ valid: 0, risky: 0, invalid: 0, unknown: 0, bounced: 0 }
|
|
869
|
-
);
|
|
870
|
-
const summaryTiles = [
|
|
871
|
-
{ label: "Valid", value: totals.valid, icon: IconMailCheck },
|
|
872
|
-
{ label: "Risky", value: totals.risky, icon: IconAlertCircle },
|
|
873
|
-
{ label: "Invalid", value: totals.invalid, icon: IconX },
|
|
874
|
-
{ label: "Unknown", value: totals.unknown, icon: IconQuestionMark },
|
|
875
|
-
{ label: "Bounced", value: totals.bounced, icon: IconAlertCircle },
|
|
876
|
-
{ label: "Bounce Rate", value: computeBounceRate(totals), icon: IconChecklist }
|
|
877
|
-
];
|
|
878
|
-
return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
879
|
-
/* @__PURE__ */ jsx(PageTitleCaption, { title: "Deliverability", caption: "Email validity breakdown and bounce health across lists" }),
|
|
880
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, sm: 3, lg: 6 }, children: summaryTiles.map((tile) => /* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: tile.icon, value: tile.value, label: tile.label }, tile.label)) }),
|
|
881
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
882
|
-
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
883
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "List ID" }),
|
|
884
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Valid" }),
|
|
885
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Risky" }),
|
|
886
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Invalid" }),
|
|
887
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Unknown" }),
|
|
888
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Bounced" }),
|
|
889
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Bounce Rate" })
|
|
890
|
-
] }) }),
|
|
891
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children: lists.map((list) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
892
|
-
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: list.listId }) }),
|
|
893
|
-
/* @__PURE__ */ jsx(Table.Td, { children: list.deliverability.valid }),
|
|
894
|
-
/* @__PURE__ */ jsx(Table.Td, { children: list.deliverability.risky }),
|
|
895
|
-
/* @__PURE__ */ jsx(Table.Td, { children: list.deliverability.invalid }),
|
|
896
|
-
/* @__PURE__ */ jsx(Table.Td, { children: list.deliverability.unknown }),
|
|
897
|
-
/* @__PURE__ */ jsx(Table.Td, { children: list.deliverability.bounced }),
|
|
898
|
-
/* @__PURE__ */ jsx(Table.Td, { children: computeBounceRate(list.deliverability) })
|
|
899
|
-
] }, list.listId)) })
|
|
900
|
-
] }) })
|
|
901
|
-
] }) }) });
|
|
902
|
-
}
|
|
903
717
|
var PAGE_SIZE_DEFAULT = 20;
|
|
904
718
|
function LeadGenListsPage() {
|
|
905
719
|
const navigate = useNavigate();
|
|
@@ -969,7 +783,16 @@ function LeadGenListsPage() {
|
|
|
969
783
|
{
|
|
970
784
|
title: "Lists",
|
|
971
785
|
caption: "Lead lists and contact organization",
|
|
972
|
-
rightSection: /* @__PURE__ */ jsx(
|
|
786
|
+
rightSection: /* @__PURE__ */ jsx(
|
|
787
|
+
Button,
|
|
788
|
+
{
|
|
789
|
+
leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 16 }),
|
|
790
|
+
onClick: () => setShowCreateList(true),
|
|
791
|
+
variant: "light",
|
|
792
|
+
size: "xs",
|
|
793
|
+
children: "New List"
|
|
794
|
+
}
|
|
795
|
+
)
|
|
973
796
|
}
|
|
974
797
|
) }),
|
|
975
798
|
/* @__PURE__ */ jsx(Paper, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
@@ -1171,17 +994,18 @@ function formatDateTime(value) {
|
|
|
1171
994
|
minute: "2-digit"
|
|
1172
995
|
});
|
|
1173
996
|
}
|
|
997
|
+
function contactDisplayName(firstName, lastName) {
|
|
998
|
+
const full = [firstName, lastName].filter(Boolean).join(" ").trim();
|
|
999
|
+
return full || "\u2014";
|
|
1000
|
+
}
|
|
1174
1001
|
function LeadGenListDetailPage({ listId }) {
|
|
1175
1002
|
const navigate = useNavigate();
|
|
1176
|
-
const [selectedStepKey, setSelectedStepKey] = useState(null);
|
|
1177
1003
|
const listQuery = useList(listId);
|
|
1178
1004
|
const progressQuery = useListProgress(listId);
|
|
1179
1005
|
const executionsQuery = useListExecutions(listId);
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
);
|
|
1184
|
-
const resourceDefinitionQuery = useResourceDefinition(selectedStep?.resourceId ?? "", !!selectedStep?.resourceId);
|
|
1006
|
+
const contactsQuery = useContacts({ listId, limit: 100, offset: 0 });
|
|
1007
|
+
const companiesQuery = useCompanies({ listId, limit: 100, offset: 0 });
|
|
1008
|
+
const [memberTab, setMemberTab] = useState("contacts");
|
|
1185
1009
|
const isLoading = listQuery.isLoading || progressQuery.isLoading || executionsQuery.isLoading;
|
|
1186
1010
|
const error = listQuery.error ?? progressQuery.error ?? executionsQuery.error;
|
|
1187
1011
|
if (isLoading) {
|
|
@@ -1195,7 +1019,7 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
1195
1019
|
Button,
|
|
1196
1020
|
{
|
|
1197
1021
|
variant: "light",
|
|
1198
|
-
size: "
|
|
1022
|
+
size: "xs",
|
|
1199
1023
|
leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }),
|
|
1200
1024
|
onClick: () => navigate({ to: "/lead-gen/lists" }),
|
|
1201
1025
|
children: "Lists"
|
|
@@ -1217,7 +1041,7 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
1217
1041
|
Button,
|
|
1218
1042
|
{
|
|
1219
1043
|
variant: "light",
|
|
1220
|
-
size: "
|
|
1044
|
+
size: "xs",
|
|
1221
1045
|
leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }),
|
|
1222
1046
|
onClick: () => navigate({ to: "/lead-gen/lists" }),
|
|
1223
1047
|
children: "Lists"
|
|
@@ -1239,7 +1063,7 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
1239
1063
|
Button,
|
|
1240
1064
|
{
|
|
1241
1065
|
variant: "light",
|
|
1242
|
-
size: "
|
|
1066
|
+
size: "xs",
|
|
1243
1067
|
leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }),
|
|
1244
1068
|
onClick: () => navigate({ to: "/lead-gen/lists" }),
|
|
1245
1069
|
children: "Lists"
|
|
@@ -1253,210 +1077,117 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
1253
1077
|
const list = listQuery.data;
|
|
1254
1078
|
const progress = progressQuery.data;
|
|
1255
1079
|
const executions = executionsQuery.data ?? [];
|
|
1256
|
-
const
|
|
1257
|
-
const
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1080
|
+
const contacts = contactsQuery.data?.data ?? [];
|
|
1081
|
+
const companies = companiesQuery.data?.data ?? [];
|
|
1082
|
+
return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1083
|
+
/* @__PURE__ */ jsx(
|
|
1084
|
+
PageTitleCaption,
|
|
1085
|
+
{
|
|
1086
|
+
title: list.name,
|
|
1087
|
+
caption: list.description ?? "Configuration, progress, and execution history for this list",
|
|
1088
|
+
rightSection: /* @__PURE__ */ jsx(
|
|
1089
|
+
Button,
|
|
1090
|
+
{
|
|
1091
|
+
variant: "light",
|
|
1092
|
+
size: "xs",
|
|
1093
|
+
leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }),
|
|
1094
|
+
onClick: () => navigate({ to: "/lead-gen/lists" }),
|
|
1095
|
+
children: "Lists"
|
|
1096
|
+
}
|
|
1097
|
+
)
|
|
1098
|
+
}
|
|
1099
|
+
),
|
|
1100
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
1101
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor(list.status), children: list.status }),
|
|
1102
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
1103
|
+
"Created ",
|
|
1104
|
+
formatDateTime(list.createdAt)
|
|
1105
|
+
] })
|
|
1106
|
+
] }),
|
|
1107
|
+
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
|
|
1108
|
+
/* @__PURE__ */ jsx(StatCard, { label: "Companies", value: progress.totalCompanies, icon: IconBuilding }),
|
|
1109
|
+
/* @__PURE__ */ jsx(StatCard, { label: "Contacts", value: progress.totalContacts, icon: IconUsers })
|
|
1110
|
+
] }),
|
|
1111
|
+
/* @__PURE__ */ jsxs(Paper, { withBorder: true, p: "md", children: [
|
|
1276
1112
|
/* @__PURE__ */ jsx(
|
|
1277
|
-
|
|
1113
|
+
CardHeader,
|
|
1278
1114
|
{
|
|
1279
|
-
|
|
1280
|
-
|
|
1115
|
+
icon: /* @__PURE__ */ jsx(IconAddressBook, { size: 16 }),
|
|
1116
|
+
title: "Members",
|
|
1281
1117
|
rightSection: /* @__PURE__ */ jsx(
|
|
1282
|
-
|
|
1118
|
+
SegmentedControl,
|
|
1283
1119
|
{
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1120
|
+
value: memberTab,
|
|
1121
|
+
onChange: (value) => setMemberTab(value),
|
|
1122
|
+
size: "xs",
|
|
1123
|
+
data: [
|
|
1124
|
+
{ label: `Contacts (${progress.totalContacts})`, value: "contacts" },
|
|
1125
|
+
{ label: `Companies (${progress.totalCompanies})`, value: "companies" }
|
|
1126
|
+
]
|
|
1289
1127
|
}
|
|
1290
1128
|
)
|
|
1291
1129
|
}
|
|
1292
1130
|
),
|
|
1293
|
-
/* @__PURE__ */
|
|
1294
|
-
/* @__PURE__ */ jsx(
|
|
1295
|
-
|
|
1296
|
-
"
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
/* @__PURE__ */ jsx(
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
/* @__PURE__ */ jsx(
|
|
1307
|
-
/* @__PURE__ */ jsx(
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", mb: "xs", children: "Pipeline Steps" }),
|
|
1311
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: pipelineSteps.length })
|
|
1312
|
-
] }),
|
|
1313
|
-
/* @__PURE__ */ jsxs(Paper, { withBorder: true, p: "md", children: [
|
|
1314
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", mb: "xs", children: "Executions" }),
|
|
1315
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: executions.length })
|
|
1316
|
-
] })
|
|
1317
|
-
] }),
|
|
1318
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
1319
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: "Pipeline Progress" }),
|
|
1320
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, sm: 3, lg: 7 }, children: stageTiles.map((tile) => /* @__PURE__ */ jsxs(Paper, { withBorder: true, p: "sm", children: [
|
|
1321
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: tile.label }),
|
|
1322
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: tile.value })
|
|
1323
|
-
] }, tile.label)) })
|
|
1324
|
-
] }) }),
|
|
1325
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
1326
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: "Deliverability" }),
|
|
1327
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, sm: 3, lg: 5 }, children: deliverabilityTiles.map((tile) => /* @__PURE__ */ jsxs(Paper, { withBorder: true, p: "sm", children: [
|
|
1328
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: tile.label }),
|
|
1329
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: tile.value })
|
|
1330
|
-
] }, tile.label)) })
|
|
1331
|
-
] }) }),
|
|
1332
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
1333
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: "Configuration" }),
|
|
1334
|
-
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, lg: 2 }, children: [
|
|
1335
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
1336
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Qualification" }),
|
|
1337
|
-
qualification ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1338
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1339
|
-
"Target: ",
|
|
1340
|
-
qualification.targetDescription
|
|
1341
|
-
] }),
|
|
1342
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1343
|
-
"Minimum reviews: ",
|
|
1344
|
-
qualification.minReviewCount
|
|
1345
|
-
] }),
|
|
1346
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1347
|
-
"Minimum rating: ",
|
|
1348
|
-
qualification.minRating
|
|
1349
|
-
] }),
|
|
1350
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1351
|
-
"Exclude franchises: ",
|
|
1352
|
-
qualification.excludeFranchises ? "Yes" : "No"
|
|
1353
|
-
] })
|
|
1354
|
-
] }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Qualification settings are not configured for this list." })
|
|
1355
|
-
] }) }),
|
|
1356
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
1357
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Enrichment + Personalization" }),
|
|
1358
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1359
|
-
"Discovery provider: ",
|
|
1360
|
-
list.config.enrichment?.emailDiscovery?.primary ?? "Inherited default"
|
|
1361
|
-
] }),
|
|
1362
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1363
|
-
"Verification provider: ",
|
|
1364
|
-
list.config.enrichment?.emailVerification?.provider ?? "Inherited default"
|
|
1365
|
-
] }),
|
|
1366
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1367
|
-
"Industry context: ",
|
|
1368
|
-
list.config.personalization?.industryContext ?? "Inherited default"
|
|
1369
|
-
] }),
|
|
1370
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1371
|
-
"Creative direction: ",
|
|
1372
|
-
list.config.personalization?.creativeDirection ?? "Inherited default"
|
|
1373
|
-
] })
|
|
1374
|
-
] }) })
|
|
1375
|
-
] }),
|
|
1376
|
-
list.config.personalization?.emailBody ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
1377
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, mb: "xs", children: "Email Body Template" }),
|
|
1378
|
-
/* @__PURE__ */ jsx(Code, { block: true, children: list.config.personalization.emailBody })
|
|
1379
|
-
] }) : null
|
|
1380
|
-
] }) }),
|
|
1381
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
1382
|
-
/* @__PURE__ */ jsx(Title, { order: 3, children: "Pipeline Steps" }),
|
|
1383
|
-
!pipelineSteps.length ? /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), color: "gray", variant: "light", children: "This list does not have any configured pipeline steps yet." }) : /* @__PURE__ */ jsxs(Table, { children: [
|
|
1384
|
-
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1385
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Order" }),
|
|
1386
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Step" }),
|
|
1387
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Resource" }),
|
|
1388
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
1389
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Action" })
|
|
1390
|
-
] }) }),
|
|
1391
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children: pipelineSteps.map((step) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1392
|
-
/* @__PURE__ */ jsx(Table.Td, { children: step.order }),
|
|
1393
|
-
/* @__PURE__ */ jsxs(Table.Td, { children: [
|
|
1394
|
-
/* @__PURE__ */ jsx(Text, { fw: 500, children: step.label }),
|
|
1395
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: step.key })
|
|
1396
|
-
] }),
|
|
1397
|
-
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Code, { children: step.resourceId }) }),
|
|
1398
|
-
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: step.enabled ? "light" : "outline", color: step.enabled ? "green" : "gray", children: step.enabled ? "Enabled" : "Disabled" }) }),
|
|
1399
|
-
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(
|
|
1400
|
-
Button,
|
|
1401
|
-
{
|
|
1402
|
-
size: "xs",
|
|
1403
|
-
variant: "light",
|
|
1404
|
-
leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
|
|
1405
|
-
disabled: !step.enabled,
|
|
1406
|
-
onClick: () => setSelectedStepKey(step.key),
|
|
1407
|
-
children: "Run"
|
|
1408
|
-
}
|
|
1409
|
-
) })
|
|
1410
|
-
] }, step.key)) })
|
|
1411
|
-
] })
|
|
1131
|
+
memberTab === "contacts" && /* @__PURE__ */ jsx(Fragment, { children: contactsQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !contacts.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No contacts attached to this list yet." }) : /* @__PURE__ */ jsxs(Table, { children: [
|
|
1132
|
+
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1133
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
|
|
1134
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Email" }),
|
|
1135
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Title" }),
|
|
1136
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
|
|
1137
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
1138
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Created" })
|
|
1139
|
+
] }) }),
|
|
1140
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: contacts.map((contact) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1141
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: contactDisplayName(contact.firstName, contact.lastName) }) }),
|
|
1142
|
+
/* @__PURE__ */ jsx(Table.Td, { children: contact.email }),
|
|
1143
|
+
/* @__PURE__ */ jsx(Table.Td, { children: contact.title ?? "\u2014" }),
|
|
1144
|
+
/* @__PURE__ */ jsx(Table.Td, { children: contact.company?.name ?? "\u2014" }),
|
|
1145
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor(contact.status), children: contact.status }) }),
|
|
1146
|
+
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime(contact.createdAt) })
|
|
1147
|
+
] }, contact.id)) })
|
|
1412
1148
|
] }) }),
|
|
1413
|
-
/* @__PURE__ */ jsx(
|
|
1414
|
-
/* @__PURE__ */ jsx(
|
|
1415
|
-
|
|
1416
|
-
/* @__PURE__ */ jsx(Table.
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
/* @__PURE__ */ jsx(Table.
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime(execution.completedAt) }),
|
|
1431
|
-
/* @__PURE__ */ jsx(Table.Td, { children: execution.durationMs == null ? "n/a" : `${execution.durationMs} ms` })
|
|
1432
|
-
] }, execution.executionId)) })
|
|
1433
|
-
] })
|
|
1149
|
+
memberTab === "companies" && /* @__PURE__ */ jsx(Fragment, { children: companiesQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : !companies.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No companies attached to this list yet." }) : /* @__PURE__ */ jsxs(Table, { children: [
|
|
1150
|
+
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1151
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
|
|
1152
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Domain" }),
|
|
1153
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Segment" }),
|
|
1154
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Contacts" }),
|
|
1155
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
1156
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Created" })
|
|
1157
|
+
] }) }),
|
|
1158
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: companies.map((company) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1159
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { fw: 500, children: company.name }) }),
|
|
1160
|
+
/* @__PURE__ */ jsx(Table.Td, { children: company.domain ?? "\u2014" }),
|
|
1161
|
+
/* @__PURE__ */ jsx(Table.Td, { children: company.segment ?? "\u2014" }),
|
|
1162
|
+
/* @__PURE__ */ jsx(Table.Td, { children: company.contactCount }),
|
|
1163
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor(company.status), children: company.status }) }),
|
|
1164
|
+
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime(company.createdAt) })
|
|
1165
|
+
] }, company.id)) })
|
|
1434
1166
|
] }) })
|
|
1435
1167
|
] }),
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
{
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
] }) });
|
|
1168
|
+
/* @__PURE__ */ jsxs(Paper, { withBorder: true, p: "md", children: [
|
|
1169
|
+
/* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 16 }), title: "Execution History" }),
|
|
1170
|
+
!executions.length ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No executions recorded for this list yet." }) : /* @__PURE__ */ jsxs(Table, { children: [
|
|
1171
|
+
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1172
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Resource" }),
|
|
1173
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
1174
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Started" }),
|
|
1175
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Completed" }),
|
|
1176
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Duration" })
|
|
1177
|
+
] }) }),
|
|
1178
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: executions.map((execution) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1179
|
+
/* @__PURE__ */ jsxs(Table.Td, { children: [
|
|
1180
|
+
/* @__PURE__ */ jsx(Text, { fw: 500, children: execution.resourceId }),
|
|
1181
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: execution.executionId })
|
|
1182
|
+
] }),
|
|
1183
|
+
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor(execution.status), children: execution.status }) }),
|
|
1184
|
+
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime(execution.createdAt) }),
|
|
1185
|
+
/* @__PURE__ */ jsx(Table.Td, { children: formatDateTime(execution.completedAt) }),
|
|
1186
|
+
/* @__PURE__ */ jsx(Table.Td, { children: execution.durationMs == null ? "n/a" : `${execution.durationMs} ms` })
|
|
1187
|
+
] }, execution.executionId)) })
|
|
1188
|
+
] })
|
|
1189
|
+
] })
|
|
1190
|
+
] }) }) });
|
|
1460
1191
|
}
|
|
1461
1192
|
var PAGE_SIZE_DEFAULT2 = 20;
|
|
1462
1193
|
function LeadGenCompaniesPage() {
|
|
@@ -1466,36 +1197,24 @@ function LeadGenCompaniesPage() {
|
|
|
1466
1197
|
const [statusFilter, setStatusFilter] = useState(null);
|
|
1467
1198
|
const [selectedCompany, setSelectedCompany] = useState(null);
|
|
1468
1199
|
const [showBatchDelete, setShowBatchDelete] = useState(false);
|
|
1469
|
-
const
|
|
1200
|
+
const pagination = usePaginationState(PAGE_SIZE_DEFAULT2, [companySearch, segmentFilter, categoryFilter, statusFilter]);
|
|
1201
|
+
const { data: companyFacets } = useCompanyFacets();
|
|
1202
|
+
const { data: pagedCompanies, isLoading: pagedCompaniesLoading, error: pagedCompaniesError } = useCompanies({
|
|
1470
1203
|
search: companySearch || void 0,
|
|
1471
1204
|
segment: segmentFilter || void 0,
|
|
1472
1205
|
category: categoryFilter || void 0,
|
|
1473
|
-
status: statusFilter
|
|
1206
|
+
status: statusFilter || void 0,
|
|
1207
|
+
limit: PAGE_SIZE_DEFAULT2,
|
|
1208
|
+
offset: pagination.offset
|
|
1474
1209
|
});
|
|
1475
1210
|
const deleteCompaniesMutation = useDeleteCompanies();
|
|
1476
|
-
const
|
|
1477
|
-
const
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
employees: (company) => company.numEmployees ?? 0,
|
|
1484
|
-
enrichment: (company) => getEnrichmentStatus(company.enrichmentData),
|
|
1485
|
-
contacts: (company) => company.contactCount
|
|
1486
|
-
}),
|
|
1487
|
-
[]
|
|
1488
|
-
);
|
|
1489
|
-
const sortedCompanies = useMemo(
|
|
1490
|
-
() => sortData(companies ?? [], sort, sortAccessors),
|
|
1491
|
-
[companies, sort, sortAccessors]
|
|
1492
|
-
);
|
|
1493
|
-
const pagination = usePaginationState(PAGE_SIZE_DEFAULT2, [companySearch, segmentFilter, categoryFilter, statusFilter], sortedCompanies.length);
|
|
1494
|
-
const paginatedCompanies = useMemo(
|
|
1495
|
-
() => sortedCompanies.slice(pagination.offset, pagination.offset + PAGE_SIZE_DEFAULT2),
|
|
1496
|
-
[sortedCompanies, pagination.offset]
|
|
1497
|
-
);
|
|
1498
|
-
const selection = useTableSelection(paginatedCompanies, sortedCompanies);
|
|
1211
|
+
const companyRows = pagedCompanies?.data ?? [];
|
|
1212
|
+
const selection = useTableSelection(companyRows);
|
|
1213
|
+
useEffect(() => {
|
|
1214
|
+
if ((pagedCompanies?.total ?? 0) === 0) return;
|
|
1215
|
+
if (companyRows.length > 0 || pagination.page === 1) return;
|
|
1216
|
+
pagination.setPage(pagination.page - 1);
|
|
1217
|
+
}, [companyRows.length, pagedCompanies?.total, pagination.page, pagination.setPage]);
|
|
1499
1218
|
function handleBatchDelete() {
|
|
1500
1219
|
deleteCompaniesMutation.mutate([...selection.selectedIds], {
|
|
1501
1220
|
onSuccess: () => {
|
|
@@ -1523,9 +1242,9 @@ function LeadGenCompaniesPage() {
|
|
|
1523
1242
|
Select,
|
|
1524
1243
|
{
|
|
1525
1244
|
placeholder: "All Segments",
|
|
1526
|
-
data:
|
|
1245
|
+
data: companyFacets?.segments ?? [],
|
|
1527
1246
|
value: segmentFilter,
|
|
1528
|
-
onChange: setSegmentFilter,
|
|
1247
|
+
onChange: (value) => setSegmentFilter(value),
|
|
1529
1248
|
style: { minWidth: 180 },
|
|
1530
1249
|
size: "sm",
|
|
1531
1250
|
clearable: true
|
|
@@ -1535,9 +1254,9 @@ function LeadGenCompaniesPage() {
|
|
|
1535
1254
|
Select,
|
|
1536
1255
|
{
|
|
1537
1256
|
placeholder: "All Categories",
|
|
1538
|
-
data:
|
|
1257
|
+
data: companyFacets?.categories ?? [],
|
|
1539
1258
|
value: categoryFilter,
|
|
1540
|
-
onChange: setCategoryFilter,
|
|
1259
|
+
onChange: (value) => setCategoryFilter(value),
|
|
1541
1260
|
style: { minWidth: 160 },
|
|
1542
1261
|
size: "sm",
|
|
1543
1262
|
clearable: true
|
|
@@ -1547,12 +1266,12 @@ function LeadGenCompaniesPage() {
|
|
|
1547
1266
|
Select,
|
|
1548
1267
|
{
|
|
1549
1268
|
placeholder: "All Statuses",
|
|
1550
|
-
data: [
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1269
|
+
data: (companyFacets?.statuses ?? []).map((status) => ({
|
|
1270
|
+
value: status,
|
|
1271
|
+
label: status[0].toUpperCase() + status.slice(1)
|
|
1272
|
+
})),
|
|
1554
1273
|
value: statusFilter,
|
|
1555
|
-
onChange: setStatusFilter,
|
|
1274
|
+
onChange: (value) => setStatusFilter(value),
|
|
1556
1275
|
style: { minWidth: 160 },
|
|
1557
1276
|
size: "sm",
|
|
1558
1277
|
clearable: true
|
|
@@ -1572,7 +1291,7 @@ function LeadGenCompaniesPage() {
|
|
|
1572
1291
|
]
|
|
1573
1292
|
}
|
|
1574
1293
|
),
|
|
1575
|
-
|
|
1294
|
+
pagedCompaniesLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : pagedCompaniesError ? /* @__PURE__ */ jsx(CenteredErrorState, { error: pagedCompaniesError, title: "Failed to load companies" }) : !companyRows.length ? /* @__PURE__ */ jsx(EmptyState, { icon: IconBuildingFactory2, title: "No companies yet", description: "Add one to get started." }) : /* @__PURE__ */ jsxs(Table, { children: [
|
|
1576
1295
|
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1577
1296
|
/* @__PURE__ */ jsx(Table.Th, { w: 40, children: /* @__PURE__ */ jsx(
|
|
1578
1297
|
Checkbox,
|
|
@@ -1582,15 +1301,15 @@ function LeadGenCompaniesPage() {
|
|
|
1582
1301
|
onChange: selection.togglePage
|
|
1583
1302
|
}
|
|
1584
1303
|
) }),
|
|
1585
|
-
/* @__PURE__ */ jsx(
|
|
1586
|
-
/* @__PURE__ */ jsx(
|
|
1587
|
-
/* @__PURE__ */ jsx(
|
|
1588
|
-
/* @__PURE__ */ jsx(
|
|
1589
|
-
/* @__PURE__ */ jsx(
|
|
1590
|
-
/* @__PURE__ */ jsx(
|
|
1591
|
-
/* @__PURE__ */ jsx(
|
|
1304
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
|
|
1305
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Domain" }),
|
|
1306
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Segment" }),
|
|
1307
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Category" }),
|
|
1308
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Employees" }),
|
|
1309
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Enrichment" }),
|
|
1310
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Contacts" })
|
|
1592
1311
|
] }) }),
|
|
1593
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children:
|
|
1312
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: companyRows.map((company) => {
|
|
1594
1313
|
const enrichStatus = getEnrichmentStatus(company.enrichmentData);
|
|
1595
1314
|
return /* @__PURE__ */ jsxs(
|
|
1596
1315
|
Table.Tr,
|
|
@@ -1628,12 +1347,12 @@ function LeadGenCompaniesPage() {
|
|
|
1628
1347
|
);
|
|
1629
1348
|
}) })
|
|
1630
1349
|
] }),
|
|
1631
|
-
|
|
1350
|
+
(pagedCompanies?.total ?? 0) > PAGE_SIZE_DEFAULT2 ? /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
1632
1351
|
Pagination,
|
|
1633
1352
|
{
|
|
1634
1353
|
value: pagination.page,
|
|
1635
1354
|
onChange: pagination.setPage,
|
|
1636
|
-
total: pagination.totalPages(
|
|
1355
|
+
total: pagination.totalPages(pagedCompanies?.total ?? 0),
|
|
1637
1356
|
size: "sm"
|
|
1638
1357
|
}
|
|
1639
1358
|
) }) : null
|
|
@@ -1663,35 +1382,23 @@ function LeadGenContactsPage() {
|
|
|
1663
1382
|
const [listFilter, setListFilter] = useState(null);
|
|
1664
1383
|
const [selectedContact, setSelectedContact] = useState(null);
|
|
1665
1384
|
const [showBatchDelete, setShowBatchDelete] = useState(false);
|
|
1385
|
+
const pagination = usePaginationState(PAGE_SIZE_DEFAULT3, [contactSearch, statusFilter, listFilter]);
|
|
1666
1386
|
const { data: lists } = useLists();
|
|
1667
|
-
const { data: contacts, isLoading: contactsLoading } = useContacts({
|
|
1387
|
+
const { data: contacts, isLoading: contactsLoading, error: contactsError } = useContacts({
|
|
1668
1388
|
search: contactSearch || void 0,
|
|
1669
|
-
contactStatus: statusFilter
|
|
1670
|
-
listId: listFilter || void 0
|
|
1389
|
+
contactStatus: statusFilter || void 0,
|
|
1390
|
+
listId: listFilter || void 0,
|
|
1391
|
+
limit: PAGE_SIZE_DEFAULT3,
|
|
1392
|
+
offset: pagination.offset
|
|
1671
1393
|
});
|
|
1672
1394
|
const deleteContactsMutation = useDeleteContacts();
|
|
1673
|
-
const
|
|
1674
|
-
const
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
status: (contact) => contact.status || "",
|
|
1681
|
-
personalized: (contact) => contact.openingLine ? "yes" : "no"
|
|
1682
|
-
}),
|
|
1683
|
-
[]
|
|
1684
|
-
);
|
|
1685
|
-
const sortedContacts = useMemo(
|
|
1686
|
-
() => sortData(contacts ?? [], sort, sortAccessors),
|
|
1687
|
-
[contacts, sort, sortAccessors]
|
|
1688
|
-
);
|
|
1689
|
-
const pagination = usePaginationState(PAGE_SIZE_DEFAULT3, [contactSearch, statusFilter, listFilter], sortedContacts.length);
|
|
1690
|
-
const paginatedContacts = useMemo(
|
|
1691
|
-
() => sortedContacts.slice(pagination.offset, pagination.offset + PAGE_SIZE_DEFAULT3),
|
|
1692
|
-
[sortedContacts, pagination.offset]
|
|
1693
|
-
);
|
|
1694
|
-
const selection = useTableSelection(paginatedContacts, sortedContacts);
|
|
1395
|
+
const contactRows = contacts?.data ?? [];
|
|
1396
|
+
const selection = useTableSelection(contactRows);
|
|
1397
|
+
useEffect(() => {
|
|
1398
|
+
if ((contacts?.total ?? 0) === 0) return;
|
|
1399
|
+
if (contactRows.length > 0 || pagination.page === 1) return;
|
|
1400
|
+
pagination.setPage(pagination.page - 1);
|
|
1401
|
+
}, [contactRows.length, contacts?.total, pagination.page, pagination.setPage]);
|
|
1695
1402
|
function handleBatchDelete() {
|
|
1696
1403
|
deleteContactsMutation.mutate([...selection.selectedIds], {
|
|
1697
1404
|
onSuccess: () => {
|
|
@@ -1724,7 +1431,7 @@ function LeadGenContactsPage() {
|
|
|
1724
1431
|
{ value: "invalid", label: "Invalid" }
|
|
1725
1432
|
],
|
|
1726
1433
|
value: statusFilter,
|
|
1727
|
-
onChange: setStatusFilter,
|
|
1434
|
+
onChange: (value) => setStatusFilter(value),
|
|
1728
1435
|
style: { minWidth: 160 },
|
|
1729
1436
|
size: "sm",
|
|
1730
1437
|
clearable: true
|
|
@@ -1736,7 +1443,7 @@ function LeadGenContactsPage() {
|
|
|
1736
1443
|
placeholder: "All Lists",
|
|
1737
1444
|
data: (lists ?? []).map((list) => ({ value: list.id, label: list.name })),
|
|
1738
1445
|
value: listFilter,
|
|
1739
|
-
onChange: setListFilter,
|
|
1446
|
+
onChange: (value) => setListFilter(value),
|
|
1740
1447
|
style: { minWidth: 200 },
|
|
1741
1448
|
size: "sm",
|
|
1742
1449
|
clearable: true
|
|
@@ -1756,7 +1463,7 @@ function LeadGenContactsPage() {
|
|
|
1756
1463
|
]
|
|
1757
1464
|
}
|
|
1758
1465
|
),
|
|
1759
|
-
contactsLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : !
|
|
1466
|
+
contactsLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : contactsError ? /* @__PURE__ */ jsx(CenteredErrorState, { error: contactsError, title: "Failed to load contacts" }) : !contactRows.length ? /* @__PURE__ */ jsx(EmptyState, { icon: IconUsers, title: "No contacts yet", description: "Add one to get started." }) : /* @__PURE__ */ jsxs(Table, { children: [
|
|
1760
1467
|
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1761
1468
|
/* @__PURE__ */ jsx(Table.Th, { w: 40, children: /* @__PURE__ */ jsx(
|
|
1762
1469
|
Checkbox,
|
|
@@ -1766,14 +1473,14 @@ function LeadGenContactsPage() {
|
|
|
1766
1473
|
onChange: selection.togglePage
|
|
1767
1474
|
}
|
|
1768
1475
|
) }),
|
|
1769
|
-
/* @__PURE__ */ jsx(
|
|
1770
|
-
/* @__PURE__ */ jsx(
|
|
1771
|
-
/* @__PURE__ */ jsx(
|
|
1772
|
-
/* @__PURE__ */ jsx(
|
|
1773
|
-
/* @__PURE__ */ jsx(
|
|
1774
|
-
/* @__PURE__ */ jsx(
|
|
1476
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
|
|
1477
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Email" }),
|
|
1478
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
|
|
1479
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Title" }),
|
|
1480
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
1481
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Personalized" })
|
|
1775
1482
|
] }) }),
|
|
1776
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children:
|
|
1483
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: contactRows.map((contact) => {
|
|
1777
1484
|
const fullName = [contact.firstName, contact.lastName].filter(Boolean).join(" ") || contact.email;
|
|
1778
1485
|
const hasPersonalization = !!contact.openingLine;
|
|
1779
1486
|
return /* @__PURE__ */ jsxs(
|
|
@@ -1811,12 +1518,12 @@ function LeadGenContactsPage() {
|
|
|
1811
1518
|
);
|
|
1812
1519
|
}) })
|
|
1813
1520
|
] }),
|
|
1814
|
-
|
|
1521
|
+
(contacts?.total ?? 0) > PAGE_SIZE_DEFAULT3 ? /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
1815
1522
|
Pagination,
|
|
1816
1523
|
{
|
|
1817
1524
|
value: pagination.page,
|
|
1818
1525
|
onChange: pagination.setPage,
|
|
1819
|
-
total: pagination.totalPages(
|
|
1526
|
+
total: pagination.totalPages(contacts?.total ?? 0),
|
|
1820
1527
|
size: "sm"
|
|
1821
1528
|
}
|
|
1822
1529
|
) }) : null
|
|
@@ -1840,4 +1547,4 @@ function LeadGenContactsPage() {
|
|
|
1840
1547
|
] }) });
|
|
1841
1548
|
}
|
|
1842
1549
|
|
|
1843
|
-
export { CompanyDetailModal, ContactDetailModal, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LIST_TEMPLATE_OPTIONS, LeadGenCompaniesPage, LeadGenContactsPage,
|
|
1550
|
+
export { CompanyDetailModal, ContactDetailModal, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LIST_TEMPLATE_OPTIONS, LeadGenCompaniesPage, LeadGenContactsPage, LeadGenListDetailPage, LeadGenListsPage, LeadGenOverviewPage, LeadGenRouteShell, LeadGenSidebar, LeadGenSidebarMiddle, LeadGenSidebarTop, buildListConfig, formatDate, getEnrichmentColor, getEnrichmentStatus, getStatusColor, leadGenManifest, useDeleteLists };
|