@elevasis/ui 2.17.0 → 2.18.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/charts/index.js +2 -2
- package/dist/{chunk-ABUDMATM.js → chunk-66VY5EMV.js} +4 -4
- package/dist/{chunk-2TDZBYXI.js → chunk-A2AZY5SF.js} +1 -1
- package/dist/{chunk-FNWWVX5N.js → chunk-B6FIIEFO.js} +245 -86
- package/dist/{chunk-MJ6YV2B5.js → chunk-DDZMBNTY.js} +1 -1
- package/dist/{chunk-R7GKX4HW.js → chunk-EY322HXF.js} +175 -78
- package/dist/{chunk-JU6UB4YA.js → chunk-FM6LSZ45.js} +3 -3
- package/dist/{chunk-OCCZRPER.js → chunk-I3LQGLUC.js} +1 -1
- package/dist/{chunk-MDO4UCEJ.js → chunk-LT33DSMO.js} +45 -80
- package/dist/{chunk-TP5NMF6K.js → chunk-P6TC4K7I.js} +3 -3
- package/dist/{chunk-TTP62HWW.js → chunk-SQPM2QDH.js} +7 -13
- package/dist/{chunk-S6CYH4RI.js → chunk-SS2UVUSG.js} +27 -5
- package/dist/{chunk-MUZIYL5Q.js → chunk-UA36WILN.js} +83 -310
- package/dist/{chunk-OXWQQCDR.js → chunk-WP3IYOVJ.js} +226 -211
- package/dist/components/index.d.ts +9 -4
- package/dist/components/index.js +32 -18
- package/dist/features/crm/index.js +5 -5
- package/dist/features/dashboard/index.js +6 -6
- package/dist/features/delivery/index.js +5 -5
- package/dist/features/lead-gen/index.d.ts +152 -16
- package/dist/features/lead-gen/index.js +9 -9
- package/dist/features/monitoring/index.js +7 -7
- package/dist/features/monitoring/requests/index.js +4 -4
- package/dist/features/operations/index.d.ts +1 -0
- package/dist/features/operations/index.js +8 -8
- package/dist/features/settings/index.js +5 -5
- package/dist/hooks/index.d.ts +359 -46
- package/dist/hooks/index.js +4 -4
- package/dist/hooks/published.d.ts +359 -46
- package/dist/hooks/published.js +4 -4
- package/dist/index.d.ts +359 -46
- package/dist/index.js +4 -4
- package/dist/provider/index.js +3 -3
- package/dist/provider/published.js +2 -2
- package/dist/types/index.d.ts +12 -6
- package/dist/zustand/index.js +2 -2
- package/package.json +3 -3
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { ResourceExecuteDialog } from './chunk-
|
|
1
|
+
import { ResourceExecuteDialog } from './chunk-WP3IYOVJ.js';
|
|
2
2
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
3
3
|
import { TableSelectionToolbar, SortableHeader } from './chunk-TUMSNGTX.js';
|
|
4
4
|
import { SubshellNavItem } from './chunk-CEWTOKE7.js';
|
|
5
5
|
import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
|
|
6
6
|
import { FilterBar } from './chunk-PDHTXPSF.js';
|
|
7
7
|
import { CustomModal } from './chunk-GBMNCNHX.js';
|
|
8
|
-
import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useList, useListProgress, useListExecutions, useResourceDefinition, useCompanies, useDeleteCompanies, useContacts, useDeleteContacts } from './chunk-
|
|
8
|
+
import { acquisitionListKeys, useListsTelemetry, useLists, useCreateList, useTableSort, sortData, usePaginationState, useTableSelection, useList, useListProgress, useListExecutions, useResourceDefinition, useCompanyFacets, useCompanies, useDeleteCompanies, useContacts, useDeleteContacts } from './chunk-EY322HXF.js';
|
|
9
9
|
import { showApiErrorNotification, showSuccessNotification } from './chunk-GRGRBWIO.js';
|
|
10
10
|
import { SubshellContentContainer } from './chunk-RX4UWZZR.js';
|
|
11
|
-
import { PageTitleCaption, CenteredErrorState, StatCard, EmptyState } from './chunk-
|
|
11
|
+
import { PageTitleCaption, CenteredErrorState, StatCard, EmptyState } from './chunk-SQPM2QDH.js';
|
|
12
12
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
13
13
|
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,
|
|
14
|
+
import { Stack, Paper, Text, Anchor, Group, Title, ActionIcon, Divider, Box, SimpleGrid, Badge, Card, Button, Center, Loader, Alert, Table, TextInput, Checkbox, Pagination, Textarea, Select, Code, Modal } from '@mantine/core';
|
|
15
|
+
import { IconLayoutGrid, IconList, IconBuilding, IconAddressBook, IconTarget, IconExternalLink, IconX, IconAlertCircle, IconPlayerPlay, IconArrowRight, IconPlus, IconSearch, IconSparkles, IconAlertTriangle, IconArrowLeft, IconClockHour4, IconBuildingFactory2, IconUsers } from '@tabler/icons-react';
|
|
16
16
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
17
17
|
import { Link, useNavigate } from '@tanstack/react-router';
|
|
18
18
|
import { useQueryClient, useMutation } from '@tanstack/react-query';
|
|
19
|
-
import { useState, useMemo } from 'react';
|
|
19
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
20
20
|
|
|
21
21
|
var LeadGenSidebarTop = () => {
|
|
22
22
|
return /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconTarget, label: "Lead Gen" });
|
|
@@ -25,8 +25,7 @@ var LEAD_GEN_ITEMS = [
|
|
|
25
25
|
{ label: "Overview", to: "/lead-gen", icon: IconLayoutGrid, exact: true },
|
|
26
26
|
{ label: "Lists", to: "/lead-gen/lists", icon: IconList, exact: false },
|
|
27
27
|
{ 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 }
|
|
28
|
+
{ label: "Contacts", to: "/lead-gen/contacts", icon: IconAddressBook, exact: false }
|
|
30
29
|
];
|
|
31
30
|
var LeadGenSidebarMiddle = ({ items = LEAD_GEN_ITEMS } = {}) => {
|
|
32
31
|
const { currentPath, navigate } = useRouterContext();
|
|
@@ -66,8 +65,7 @@ var LEAD_GEN_ROUTE_LINKS = [
|
|
|
66
65
|
{ label: "Overview", to: "/lead-gen" },
|
|
67
66
|
{ label: "Lists", to: "/lead-gen/lists" },
|
|
68
67
|
{ label: "Companies", to: "/lead-gen/companies" },
|
|
69
|
-
{ label: "Contacts", to: "/lead-gen/contacts" }
|
|
70
|
-
{ label: "Deliverability", to: "/lead-gen/deliverability" }
|
|
68
|
+
{ label: "Contacts", to: "/lead-gen/contacts" }
|
|
71
69
|
];
|
|
72
70
|
function LeadGenRouteShell({
|
|
73
71
|
title,
|
|
@@ -121,7 +119,10 @@ function formatName(parts, fallback) {
|
|
|
121
119
|
const name = parts.filter(Boolean).join(" ").trim();
|
|
122
120
|
return name || fallback;
|
|
123
121
|
}
|
|
124
|
-
function CompanyDetailModal({
|
|
122
|
+
function CompanyDetailModal({
|
|
123
|
+
company,
|
|
124
|
+
onClose
|
|
125
|
+
}) {
|
|
125
126
|
return /* @__PURE__ */ jsx(CustomModal, { opened: !!company, onClose, size: "xl", children: company ? /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
126
127
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
127
128
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -185,7 +186,10 @@ function CompanyDetailModal({ company, onClose }) {
|
|
|
185
186
|
] })
|
|
186
187
|
] }) : null });
|
|
187
188
|
}
|
|
188
|
-
function ContactDetailModal({
|
|
189
|
+
function ContactDetailModal({
|
|
190
|
+
contact,
|
|
191
|
+
onClose
|
|
192
|
+
}) {
|
|
189
193
|
return /* @__PURE__ */ jsx(CustomModal, { opened: !!contact, onClose, size: "xl", children: contact ? /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
190
194
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
191
195
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -441,23 +445,6 @@ function useDeleteLists() {
|
|
|
441
445
|
}
|
|
442
446
|
});
|
|
443
447
|
}
|
|
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
448
|
function computeBacklog(current, completed) {
|
|
462
449
|
return Math.max(current - completed, 0);
|
|
463
450
|
}
|
|
@@ -545,8 +532,8 @@ function getPrimaryAction({
|
|
|
545
532
|
return {
|
|
546
533
|
title: `Resolve ${formatCountLabel(deliverabilityRiskCount, "deliverability risk")}`,
|
|
547
534
|
detail: "Risky, invalid, or bounced records are the main campaign health issue right now.",
|
|
548
|
-
buttonLabel: "
|
|
549
|
-
buttonTo: "/lead-gen/
|
|
535
|
+
buttonLabel: "Review lists",
|
|
536
|
+
buttonTo: "/lead-gen/lists",
|
|
550
537
|
tone: "orange"
|
|
551
538
|
};
|
|
552
539
|
}
|
|
@@ -576,24 +563,12 @@ function getPrimaryAction({
|
|
|
576
563
|
tone: "gray"
|
|
577
564
|
};
|
|
578
565
|
}
|
|
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
566
|
function LeadGenOverviewPage() {
|
|
590
567
|
const navigate = useNavigate();
|
|
591
568
|
const telemetryQuery = useListsTelemetry();
|
|
592
569
|
const listsQuery = useLists();
|
|
593
570
|
const data = telemetryQuery.data;
|
|
594
571
|
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
572
|
const stageTotals = data?.reduce(
|
|
598
573
|
(acc, list) => ({
|
|
599
574
|
populated: acc.populated + list.stageCounts.populated,
|
|
@@ -605,7 +580,7 @@ function LeadGenOverviewPage() {
|
|
|
605
580
|
uploaded: acc.uploaded + list.stageCounts.uploaded
|
|
606
581
|
}),
|
|
607
582
|
{ populated: 0, extracted: 0, qualified: 0, discovered: 0, verified: 0, personalized: 0, uploaded: 0 }
|
|
608
|
-
) ?? {
|
|
583
|
+
) ?? { discovered: 0, verified: 0, personalized: 0, uploaded: 0 };
|
|
609
584
|
const deliverabilityTotals = data?.reduce(
|
|
610
585
|
(acc, list) => ({
|
|
611
586
|
valid: acc.valid + list.deliverability.valid,
|
|
@@ -623,10 +598,10 @@ function LeadGenOverviewPage() {
|
|
|
623
598
|
const deliverabilityRiskCount = deliverabilityTotals.risky + deliverabilityTotals.invalid + deliverabilityTotals.bounced;
|
|
624
599
|
const totalLists = data?.length ?? 0;
|
|
625
600
|
const summaryLine = [
|
|
626
|
-
`${totalLists} ${totalLists === 1 ? "list" : "lists"}
|
|
601
|
+
`${totalLists} total ${totalLists === 1 ? "list" : "lists"}`,
|
|
627
602
|
`${formatCountLabel(uploadBacklog, "contact")} ready for upload`,
|
|
628
603
|
deliverabilityRiskCount === 0 ? "no risks" : `${formatCountLabel(deliverabilityRiskCount, "risk")}`
|
|
629
|
-
].join("
|
|
604
|
+
].join(" | ");
|
|
630
605
|
const primaryAction = getPrimaryAction({
|
|
631
606
|
uploadBacklog,
|
|
632
607
|
personalizationBacklog,
|
|
@@ -635,41 +610,12 @@ function LeadGenOverviewPage() {
|
|
|
635
610
|
activeListCount,
|
|
636
611
|
totalLists
|
|
637
612
|
});
|
|
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
613
|
const overviewRows = data?.map((list) => {
|
|
666
614
|
const listMeta = listMetaById.get(list.listId);
|
|
667
|
-
const completionRatio = computeCompletionRatio(list.stageCounts.populated, list.stageCounts.personalized);
|
|
668
615
|
const nextFocus = getNextFocus(list);
|
|
669
616
|
return {
|
|
670
617
|
...list,
|
|
671
618
|
name: listMeta?.name ?? `List ${list.listId.slice(0, 8)}`,
|
|
672
|
-
completionRatio,
|
|
673
619
|
nextFocus,
|
|
674
620
|
status: getOverviewStatus(list)
|
|
675
621
|
};
|
|
@@ -688,15 +634,12 @@ function LeadGenOverviewPage() {
|
|
|
688
634
|
{
|
|
689
635
|
title: "Lead Gen Overview",
|
|
690
636
|
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
|
-
] })
|
|
637
|
+
rightSection: /* @__PURE__ */ jsx(Button, { component: Link, to: "/lead-gen/lists", size: "sm", variant: "light", children: "Lists" })
|
|
695
638
|
}
|
|
696
639
|
),
|
|
697
640
|
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
641
|
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 3 }, children: [
|
|
699
|
-
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconPlayerPlay, value:
|
|
642
|
+
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconPlayerPlay, value: totalLists, label: "Total Lists" }),
|
|
700
643
|
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconArrowRight, value: uploadBacklog, label: "Ready Contacts" }),
|
|
701
644
|
/* @__PURE__ */ jsx(StatCard, { variant: "hero", icon: IconAlertCircle, value: deliverabilityRiskCount, label: "At Risk" })
|
|
702
645
|
] }),
|
|
@@ -709,7 +652,7 @@ function LeadGenOverviewPage() {
|
|
|
709
652
|
] }),
|
|
710
653
|
/* @__PURE__ */ jsx(Button, { component: Link, to: primaryAction.buttonTo, size: "sm", variant: "light", children: primaryAction.buttonLabel })
|
|
711
654
|
] }),
|
|
712
|
-
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md:
|
|
655
|
+
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, md: 2 }, children: [
|
|
713
656
|
/* @__PURE__ */ jsxs(Card, { withBorder: true, p: "sm", children: [
|
|
714
657
|
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", tt: "uppercase", fw: 600, children: "Verification" }),
|
|
715
658
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-end", mt: 6, children: [
|
|
@@ -723,39 +666,9 @@ function LeadGenOverviewPage() {
|
|
|
723
666
|
/* @__PURE__ */ jsx(Title, { order: 4, children: personalizationBacklog }),
|
|
724
667
|
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "ready" })
|
|
725
668
|
] })
|
|
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
669
|
] })
|
|
734
670
|
] })
|
|
735
671
|
] }) }),
|
|
736
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
737
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-end", children: [
|
|
738
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
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,
|
|
751
|
-
{
|
|
752
|
-
label: stage.label,
|
|
753
|
-
value: stage.value,
|
|
754
|
-
ratio: stage.ratio
|
|
755
|
-
},
|
|
756
|
-
stage.label
|
|
757
|
-
)) })
|
|
758
|
-
] }) }),
|
|
759
672
|
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
760
673
|
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-end", children: [
|
|
761
674
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -770,7 +683,6 @@ function LeadGenOverviewPage() {
|
|
|
770
683
|
/* @__PURE__ */ jsx(Table.Th, { children: "Companies" }),
|
|
771
684
|
/* @__PURE__ */ jsx(Table.Th, { children: "Contacts" }),
|
|
772
685
|
/* @__PURE__ */ jsx(Table.Th, { children: "Next Focus" }),
|
|
773
|
-
/* @__PURE__ */ jsx(Table.Th, { children: "Progress" }),
|
|
774
686
|
/* @__PURE__ */ jsx(Table.Th, { children: "Status" })
|
|
775
687
|
] }) }),
|
|
776
688
|
/* @__PURE__ */ jsx(Table.Tbody, { children: overviewRows.map((list) => /* @__PURE__ */ jsxs(
|
|
@@ -789,25 +701,6 @@ function LeadGenOverviewPage() {
|
|
|
789
701
|
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: list.nextFocus.label }),
|
|
790
702
|
/* @__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
703
|
] }) }),
|
|
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
704
|
/* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: list.status.color, children: list.status.label }) })
|
|
812
705
|
]
|
|
813
706
|
},
|
|
@@ -818,88 +711,6 @@ function LeadGenOverviewPage() {
|
|
|
818
711
|
] })
|
|
819
712
|
] }) }) });
|
|
820
713
|
}
|
|
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
714
|
var PAGE_SIZE_DEFAULT = 20;
|
|
904
715
|
function LeadGenListsPage() {
|
|
905
716
|
const navigate = useNavigate();
|
|
@@ -1264,13 +1075,6 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
1264
1075
|
{ label: "Personalized", value: progress.stageCounts.personalized },
|
|
1265
1076
|
{ label: "Uploaded", value: progress.stageCounts.uploaded }
|
|
1266
1077
|
];
|
|
1267
|
-
const deliverabilityTiles = [
|
|
1268
|
-
{ label: "Valid", value: progress.deliverability.valid },
|
|
1269
|
-
{ label: "Risky", value: progress.deliverability.risky },
|
|
1270
|
-
{ label: "Invalid", value: progress.deliverability.invalid },
|
|
1271
|
-
{ label: "Unknown", value: progress.deliverability.unknown },
|
|
1272
|
-
{ label: "Bounced", value: progress.deliverability.bounced }
|
|
1273
|
-
];
|
|
1274
1078
|
return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsxs(PageContainer, { children: [
|
|
1275
1079
|
/* @__PURE__ */ jsxs(Stack, { children: [
|
|
1276
1080
|
/* @__PURE__ */ jsx(
|
|
@@ -1322,13 +1126,6 @@ function LeadGenListDetailPage({ listId }) {
|
|
|
1322
1126
|
/* @__PURE__ */ jsx(Title, { order: 4, children: tile.value })
|
|
1323
1127
|
] }, tile.label)) })
|
|
1324
1128
|
] }) }),
|
|
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
1129
|
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
1333
1130
|
/* @__PURE__ */ jsx(Title, { order: 3, children: "Configuration" }),
|
|
1334
1131
|
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, lg: 2 }, children: [
|
|
@@ -1466,36 +1263,24 @@ function LeadGenCompaniesPage() {
|
|
|
1466
1263
|
const [statusFilter, setStatusFilter] = useState(null);
|
|
1467
1264
|
const [selectedCompany, setSelectedCompany] = useState(null);
|
|
1468
1265
|
const [showBatchDelete, setShowBatchDelete] = useState(false);
|
|
1469
|
-
const
|
|
1266
|
+
const pagination = usePaginationState(PAGE_SIZE_DEFAULT2, [companySearch, segmentFilter, categoryFilter, statusFilter]);
|
|
1267
|
+
const { data: companyFacets } = useCompanyFacets();
|
|
1268
|
+
const { data: pagedCompanies, isLoading: pagedCompaniesLoading, error: pagedCompaniesError } = useCompanies({
|
|
1470
1269
|
search: companySearch || void 0,
|
|
1471
1270
|
segment: segmentFilter || void 0,
|
|
1472
1271
|
category: categoryFilter || void 0,
|
|
1473
|
-
status: statusFilter
|
|
1272
|
+
status: statusFilter || void 0,
|
|
1273
|
+
limit: PAGE_SIZE_DEFAULT2,
|
|
1274
|
+
offset: pagination.offset
|
|
1474
1275
|
});
|
|
1475
1276
|
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);
|
|
1277
|
+
const companyRows = pagedCompanies?.data ?? [];
|
|
1278
|
+
const selection = useTableSelection(companyRows);
|
|
1279
|
+
useEffect(() => {
|
|
1280
|
+
if ((pagedCompanies?.total ?? 0) === 0) return;
|
|
1281
|
+
if (companyRows.length > 0 || pagination.page === 1) return;
|
|
1282
|
+
pagination.setPage(pagination.page - 1);
|
|
1283
|
+
}, [companyRows.length, pagedCompanies?.total, pagination.page, pagination.setPage]);
|
|
1499
1284
|
function handleBatchDelete() {
|
|
1500
1285
|
deleteCompaniesMutation.mutate([...selection.selectedIds], {
|
|
1501
1286
|
onSuccess: () => {
|
|
@@ -1523,9 +1308,9 @@ function LeadGenCompaniesPage() {
|
|
|
1523
1308
|
Select,
|
|
1524
1309
|
{
|
|
1525
1310
|
placeholder: "All Segments",
|
|
1526
|
-
data:
|
|
1311
|
+
data: companyFacets?.segments ?? [],
|
|
1527
1312
|
value: segmentFilter,
|
|
1528
|
-
onChange: setSegmentFilter,
|
|
1313
|
+
onChange: (value) => setSegmentFilter(value),
|
|
1529
1314
|
style: { minWidth: 180 },
|
|
1530
1315
|
size: "sm",
|
|
1531
1316
|
clearable: true
|
|
@@ -1535,9 +1320,9 @@ function LeadGenCompaniesPage() {
|
|
|
1535
1320
|
Select,
|
|
1536
1321
|
{
|
|
1537
1322
|
placeholder: "All Categories",
|
|
1538
|
-
data:
|
|
1323
|
+
data: companyFacets?.categories ?? [],
|
|
1539
1324
|
value: categoryFilter,
|
|
1540
|
-
onChange: setCategoryFilter,
|
|
1325
|
+
onChange: (value) => setCategoryFilter(value),
|
|
1541
1326
|
style: { minWidth: 160 },
|
|
1542
1327
|
size: "sm",
|
|
1543
1328
|
clearable: true
|
|
@@ -1547,12 +1332,12 @@ function LeadGenCompaniesPage() {
|
|
|
1547
1332
|
Select,
|
|
1548
1333
|
{
|
|
1549
1334
|
placeholder: "All Statuses",
|
|
1550
|
-
data: [
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1335
|
+
data: (companyFacets?.statuses ?? []).map((status) => ({
|
|
1336
|
+
value: status,
|
|
1337
|
+
label: status[0].toUpperCase() + status.slice(1)
|
|
1338
|
+
})),
|
|
1554
1339
|
value: statusFilter,
|
|
1555
|
-
onChange: setStatusFilter,
|
|
1340
|
+
onChange: (value) => setStatusFilter(value),
|
|
1556
1341
|
style: { minWidth: 160 },
|
|
1557
1342
|
size: "sm",
|
|
1558
1343
|
clearable: true
|
|
@@ -1572,7 +1357,7 @@ function LeadGenCompaniesPage() {
|
|
|
1572
1357
|
]
|
|
1573
1358
|
}
|
|
1574
1359
|
),
|
|
1575
|
-
|
|
1360
|
+
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
1361
|
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1577
1362
|
/* @__PURE__ */ jsx(Table.Th, { w: 40, children: /* @__PURE__ */ jsx(
|
|
1578
1363
|
Checkbox,
|
|
@@ -1582,15 +1367,15 @@ function LeadGenCompaniesPage() {
|
|
|
1582
1367
|
onChange: selection.togglePage
|
|
1583
1368
|
}
|
|
1584
1369
|
) }),
|
|
1585
|
-
/* @__PURE__ */ jsx(
|
|
1586
|
-
/* @__PURE__ */ jsx(
|
|
1587
|
-
/* @__PURE__ */ jsx(
|
|
1588
|
-
/* @__PURE__ */ jsx(
|
|
1589
|
-
/* @__PURE__ */ jsx(
|
|
1590
|
-
/* @__PURE__ */ jsx(
|
|
1591
|
-
/* @__PURE__ */ jsx(
|
|
1370
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
|
|
1371
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Domain" }),
|
|
1372
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Segment" }),
|
|
1373
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Category" }),
|
|
1374
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Employees" }),
|
|
1375
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Enrichment" }),
|
|
1376
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Contacts" })
|
|
1592
1377
|
] }) }),
|
|
1593
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children:
|
|
1378
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: companyRows.map((company) => {
|
|
1594
1379
|
const enrichStatus = getEnrichmentStatus(company.enrichmentData);
|
|
1595
1380
|
return /* @__PURE__ */ jsxs(
|
|
1596
1381
|
Table.Tr,
|
|
@@ -1628,12 +1413,12 @@ function LeadGenCompaniesPage() {
|
|
|
1628
1413
|
);
|
|
1629
1414
|
}) })
|
|
1630
1415
|
] }),
|
|
1631
|
-
|
|
1416
|
+
(pagedCompanies?.total ?? 0) > PAGE_SIZE_DEFAULT2 ? /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
1632
1417
|
Pagination,
|
|
1633
1418
|
{
|
|
1634
1419
|
value: pagination.page,
|
|
1635
1420
|
onChange: pagination.setPage,
|
|
1636
|
-
total: pagination.totalPages(
|
|
1421
|
+
total: pagination.totalPages(pagedCompanies?.total ?? 0),
|
|
1637
1422
|
size: "sm"
|
|
1638
1423
|
}
|
|
1639
1424
|
) }) : null
|
|
@@ -1663,35 +1448,23 @@ function LeadGenContactsPage() {
|
|
|
1663
1448
|
const [listFilter, setListFilter] = useState(null);
|
|
1664
1449
|
const [selectedContact, setSelectedContact] = useState(null);
|
|
1665
1450
|
const [showBatchDelete, setShowBatchDelete] = useState(false);
|
|
1451
|
+
const pagination = usePaginationState(PAGE_SIZE_DEFAULT3, [contactSearch, statusFilter, listFilter]);
|
|
1666
1452
|
const { data: lists } = useLists();
|
|
1667
|
-
const { data: contacts, isLoading: contactsLoading } = useContacts({
|
|
1453
|
+
const { data: contacts, isLoading: contactsLoading, error: contactsError } = useContacts({
|
|
1668
1454
|
search: contactSearch || void 0,
|
|
1669
|
-
contactStatus: statusFilter
|
|
1670
|
-
listId: listFilter || void 0
|
|
1455
|
+
contactStatus: statusFilter || void 0,
|
|
1456
|
+
listId: listFilter || void 0,
|
|
1457
|
+
limit: PAGE_SIZE_DEFAULT3,
|
|
1458
|
+
offset: pagination.offset
|
|
1671
1459
|
});
|
|
1672
1460
|
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);
|
|
1461
|
+
const contactRows = contacts?.data ?? [];
|
|
1462
|
+
const selection = useTableSelection(contactRows);
|
|
1463
|
+
useEffect(() => {
|
|
1464
|
+
if ((contacts?.total ?? 0) === 0) return;
|
|
1465
|
+
if (contactRows.length > 0 || pagination.page === 1) return;
|
|
1466
|
+
pagination.setPage(pagination.page - 1);
|
|
1467
|
+
}, [contactRows.length, contacts?.total, pagination.page, pagination.setPage]);
|
|
1695
1468
|
function handleBatchDelete() {
|
|
1696
1469
|
deleteContactsMutation.mutate([...selection.selectedIds], {
|
|
1697
1470
|
onSuccess: () => {
|
|
@@ -1724,7 +1497,7 @@ function LeadGenContactsPage() {
|
|
|
1724
1497
|
{ value: "invalid", label: "Invalid" }
|
|
1725
1498
|
],
|
|
1726
1499
|
value: statusFilter,
|
|
1727
|
-
onChange: setStatusFilter,
|
|
1500
|
+
onChange: (value) => setStatusFilter(value),
|
|
1728
1501
|
style: { minWidth: 160 },
|
|
1729
1502
|
size: "sm",
|
|
1730
1503
|
clearable: true
|
|
@@ -1736,7 +1509,7 @@ function LeadGenContactsPage() {
|
|
|
1736
1509
|
placeholder: "All Lists",
|
|
1737
1510
|
data: (lists ?? []).map((list) => ({ value: list.id, label: list.name })),
|
|
1738
1511
|
value: listFilter,
|
|
1739
|
-
onChange: setListFilter,
|
|
1512
|
+
onChange: (value) => setListFilter(value),
|
|
1740
1513
|
style: { minWidth: 200 },
|
|
1741
1514
|
size: "sm",
|
|
1742
1515
|
clearable: true
|
|
@@ -1756,7 +1529,7 @@ function LeadGenContactsPage() {
|
|
|
1756
1529
|
]
|
|
1757
1530
|
}
|
|
1758
1531
|
),
|
|
1759
|
-
contactsLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : !
|
|
1532
|
+
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
1533
|
/* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
1761
1534
|
/* @__PURE__ */ jsx(Table.Th, { w: 40, children: /* @__PURE__ */ jsx(
|
|
1762
1535
|
Checkbox,
|
|
@@ -1766,14 +1539,14 @@ function LeadGenContactsPage() {
|
|
|
1766
1539
|
onChange: selection.togglePage
|
|
1767
1540
|
}
|
|
1768
1541
|
) }),
|
|
1769
|
-
/* @__PURE__ */ jsx(
|
|
1770
|
-
/* @__PURE__ */ jsx(
|
|
1771
|
-
/* @__PURE__ */ jsx(
|
|
1772
|
-
/* @__PURE__ */ jsx(
|
|
1773
|
-
/* @__PURE__ */ jsx(
|
|
1774
|
-
/* @__PURE__ */ jsx(
|
|
1542
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Name" }),
|
|
1543
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Email" }),
|
|
1544
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Company" }),
|
|
1545
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Title" }),
|
|
1546
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
|
|
1547
|
+
/* @__PURE__ */ jsx(Table.Th, { children: "Personalized" })
|
|
1775
1548
|
] }) }),
|
|
1776
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children:
|
|
1549
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: contactRows.map((contact) => {
|
|
1777
1550
|
const fullName = [contact.firstName, contact.lastName].filter(Boolean).join(" ") || contact.email;
|
|
1778
1551
|
const hasPersonalization = !!contact.openingLine;
|
|
1779
1552
|
return /* @__PURE__ */ jsxs(
|
|
@@ -1811,12 +1584,12 @@ function LeadGenContactsPage() {
|
|
|
1811
1584
|
);
|
|
1812
1585
|
}) })
|
|
1813
1586
|
] }),
|
|
1814
|
-
|
|
1587
|
+
(contacts?.total ?? 0) > PAGE_SIZE_DEFAULT3 ? /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
1815
1588
|
Pagination,
|
|
1816
1589
|
{
|
|
1817
1590
|
value: pagination.page,
|
|
1818
1591
|
onChange: pagination.setPage,
|
|
1819
|
-
total: pagination.totalPages(
|
|
1592
|
+
total: pagination.totalPages(contacts?.total ?? 0),
|
|
1820
1593
|
size: "sm"
|
|
1821
1594
|
}
|
|
1822
1595
|
) }) : null
|
|
@@ -1840,4 +1613,4 @@ function LeadGenContactsPage() {
|
|
|
1840
1613
|
] }) });
|
|
1841
1614
|
}
|
|
1842
1615
|
|
|
1843
|
-
export { CompanyDetailModal, ContactDetailModal, LEAD_GEN_ITEMS, LEAD_GEN_ROUTE_LINKS, LIST_TEMPLATE_OPTIONS, LeadGenCompaniesPage, LeadGenContactsPage,
|
|
1616
|
+
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 };
|