@coursebuilder/analytics 1.1.0 → 1.1.2-canary.0.0c9beb2ae
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.d.ts +22 -2
- package/dist/api/index.js +40 -5
- package/dist/api/index.js.map +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +43 -1
- package/dist/catalog.js.map +1 -1
- package/dist/components/index.d.ts +46 -1
- package/dist/components/index.js +200 -8
- package/dist/components/index.js.map +1 -1
- package/dist/engine.js +94 -6
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +94 -6
- package/dist/index.js.map +1 -1
- package/dist/providers/database.d.ts +174 -2
- package/dist/providers/database.js +711 -20
- package/dist/providers/database.js.map +1 -1
- package/dist/providers/index.js +713 -22
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/survey.d.ts +1 -1
- package/dist/providers/survey.js +2 -2
- package/dist/providers/survey.js.map +1 -1
- package/dist/types.d.ts +189 -3
- package/package.json +7 -5
- package/src/api/catalog-handler.ts +44 -2
- package/src/api/token-handler.ts +3 -2
- package/src/catalog.ts +49 -1
- package/src/components/omnibus-dashboard.tsx +340 -6
- package/src/engine.ts +69 -8
- package/src/providers/attribution-recovery.test.ts +63 -0
- package/src/providers/attribution-recovery.ts +97 -0
- package/src/providers/database.ts +880 -42
- package/src/providers/survey.ts +3 -1
- package/src/types.ts +215 -2
package/dist/components/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
|
|
4
4
|
// src/components/omnibus-dashboard.tsx
|
|
5
5
|
import React3, { useState as useState2, useTransition } from "react";
|
|
6
|
-
import { CheckIcon, ChevronDownIcon, ClipboardIcon, ClipboardListIcon, ClockIcon, DollarSignIcon, ExternalLinkIcon, FilmIcon, GlobeIcon, LinkIcon, Loader2Icon, MousePointerClickIcon, PlayIcon, ShoppingCartIcon, TrendingUpIcon } from "lucide-react";
|
|
6
|
+
import { CheckIcon, ChevronDownIcon, ClipboardIcon, ClipboardListIcon, ClockIcon, DollarSignIcon, ExternalLinkIcon, FilmIcon, GlobeIcon, LinkIcon, Loader2Icon, MousePointerClickIcon, PlayIcon, ShoppingCartIcon, TrendingUpIcon, RouteIcon } from "lucide-react";
|
|
7
7
|
import { parseAsStringLiteral, useQueryState } from "nuqs";
|
|
8
8
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@coursebuilder/ui";
|
|
9
9
|
|
|
@@ -684,6 +684,88 @@ function ShortlinksCard({ shortlinks, totalClicks }) {
|
|
|
684
684
|
}), expanded ? "Show less" : `Show ${shortlinks.length - 10} more`)));
|
|
685
685
|
}
|
|
686
686
|
__name(ShortlinksCard, "ShortlinksCard");
|
|
687
|
+
function fmtPct(v) {
|
|
688
|
+
return `${v.toFixed(1)}%`;
|
|
689
|
+
}
|
|
690
|
+
__name(fmtPct, "fmtPct");
|
|
691
|
+
function TrafficBreakdownTable({ title, label, rows, getName }) {
|
|
692
|
+
if (!rows.length)
|
|
693
|
+
return null;
|
|
694
|
+
return /* @__PURE__ */ React3.createElement("section", {
|
|
695
|
+
className: "min-w-0"
|
|
696
|
+
}, /* @__PURE__ */ React3.createElement("div", {
|
|
697
|
+
className: "mb-2 flex items-baseline justify-between gap-2"
|
|
698
|
+
}, /* @__PURE__ */ React3.createElement("h3", {
|
|
699
|
+
className: "text-sm font-semibold"
|
|
700
|
+
}, title), /* @__PURE__ */ React3.createElement("span", {
|
|
701
|
+
className: "text-muted-foreground text-[11px]"
|
|
702
|
+
}, "Top ", rows.length)), /* @__PURE__ */ React3.createElement("div", {
|
|
703
|
+
className: "overflow-x-auto rounded-xl border border-border/50"
|
|
704
|
+
}, /* @__PURE__ */ React3.createElement("table", {
|
|
705
|
+
className: "w-full min-w-[440px] text-left text-sm"
|
|
706
|
+
}, /* @__PURE__ */ React3.createElement("thead", {
|
|
707
|
+
className: "bg-muted/30 text-muted-foreground text-[11px] uppercase tracking-wide"
|
|
708
|
+
}, /* @__PURE__ */ React3.createElement("tr", null, /* @__PURE__ */ React3.createElement("th", {
|
|
709
|
+
className: "px-3 py-2 font-medium"
|
|
710
|
+
}, label), /* @__PURE__ */ React3.createElement("th", {
|
|
711
|
+
className: "px-3 py-2 text-right font-medium"
|
|
712
|
+
}, "Sessions"), /* @__PURE__ */ React3.createElement("th", {
|
|
713
|
+
className: "px-3 py-2 text-right font-medium"
|
|
714
|
+
}, "Users"), /* @__PURE__ */ React3.createElement("th", {
|
|
715
|
+
className: "px-3 py-2 text-right font-medium"
|
|
716
|
+
}, "In rows"), /* @__PURE__ */ React3.createElement("th", {
|
|
717
|
+
className: "px-3 py-2 text-right font-medium"
|
|
718
|
+
}, "Of traffic"))), /* @__PURE__ */ React3.createElement("tbody", null, rows.map((row) => /* @__PURE__ */ React3.createElement("tr", {
|
|
719
|
+
key: getName(row),
|
|
720
|
+
className: "border-t border-border/40 tabular-nums"
|
|
721
|
+
}, /* @__PURE__ */ React3.createElement("td", {
|
|
722
|
+
className: "max-w-[220px] truncate px-3 py-2 font-medium"
|
|
723
|
+
}, getName(row)), /* @__PURE__ */ React3.createElement("td", {
|
|
724
|
+
className: "px-3 py-2 text-right"
|
|
725
|
+
}, row.sessions.toLocaleString()), /* @__PURE__ */ React3.createElement("td", {
|
|
726
|
+
className: "px-3 py-2 text-right"
|
|
727
|
+
}, row.users.toLocaleString()), /* @__PURE__ */ React3.createElement("td", {
|
|
728
|
+
className: "px-3 py-2 text-right"
|
|
729
|
+
}, fmtPct(row.sessionPercent)), /* @__PURE__ */ React3.createElement("td", {
|
|
730
|
+
className: "px-3 py-2 text-right"
|
|
731
|
+
}, fmtPct(row.trafficSessionPercent))))))));
|
|
732
|
+
}
|
|
733
|
+
__name(TrafficBreakdownTable, "TrafficBreakdownTable");
|
|
734
|
+
function TrafficBreakdownsCard({ traffic }) {
|
|
735
|
+
const deviceCategories = traffic.deviceCategories ?? [];
|
|
736
|
+
const operatingSystems = traffic.operatingSystems ?? [];
|
|
737
|
+
const screenResolutions = traffic.screenResolutions ?? [];
|
|
738
|
+
if (deviceCategories.length === 0 && operatingSystems.length === 0 && screenResolutions.length === 0) {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
return /* @__PURE__ */ React3.createElement(Card, null, /* @__PURE__ */ React3.createElement(CardHeader, null, /* @__PURE__ */ React3.createElement("div", {
|
|
742
|
+
className: "flex items-center gap-2.5"
|
|
743
|
+
}, /* @__PURE__ */ React3.createElement(GlobeIcon, {
|
|
744
|
+
className: "text-muted-foreground h-4 w-4"
|
|
745
|
+
}), /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement(CardTitle, {
|
|
746
|
+
className: "text-sm font-semibold"
|
|
747
|
+
}, "Traffic Details"), /* @__PURE__ */ React3.createElement(CardDescription, {
|
|
748
|
+
className: "text-[11px]"
|
|
749
|
+
}, "Device, OS, and screen share. In rows is share inside the table. Of traffic is share of total sessions.")))), /* @__PURE__ */ React3.createElement(CardContent, null, /* @__PURE__ */ React3.createElement("div", {
|
|
750
|
+
className: "grid gap-4 xl:grid-cols-3"
|
|
751
|
+
}, /* @__PURE__ */ React3.createElement(TrafficBreakdownTable, {
|
|
752
|
+
title: "Device category",
|
|
753
|
+
label: "Device",
|
|
754
|
+
rows: deviceCategories,
|
|
755
|
+
getName: (row) => row.deviceCategory
|
|
756
|
+
}), /* @__PURE__ */ React3.createElement(TrafficBreakdownTable, {
|
|
757
|
+
title: "Operating systems",
|
|
758
|
+
label: "OS",
|
|
759
|
+
rows: operatingSystems.slice(0, 10),
|
|
760
|
+
getName: (row) => row.operatingSystem
|
|
761
|
+
}), /* @__PURE__ */ React3.createElement(TrafficBreakdownTable, {
|
|
762
|
+
title: "Screen resolutions",
|
|
763
|
+
label: "Resolution",
|
|
764
|
+
rows: screenResolutions.slice(0, 10),
|
|
765
|
+
getName: (row) => row.screenResolution
|
|
766
|
+
}))));
|
|
767
|
+
}
|
|
768
|
+
__name(TrafficBreakdownsCard, "TrafficBreakdownsCard");
|
|
687
769
|
var RANGES = [
|
|
688
770
|
{
|
|
689
771
|
value: "24h",
|
|
@@ -731,6 +813,7 @@ function OmnibusDashboard({ data, initialRange, appName, surveyDrilldownHref })
|
|
|
731
813
|
const hasTraffic = data.traffic != null;
|
|
732
814
|
const hasSurveys = data.surveySegments != null && data.surveySegments.length > 0;
|
|
733
815
|
const hasSurveyCorrelation = data.surveyCorrelation != null;
|
|
816
|
+
const hasValuePaths = data.valuePaths != null && data.valuePaths.contacts > 0;
|
|
734
817
|
const hasShortlinks = data.shortlinks.length > 0;
|
|
735
818
|
return /* @__PURE__ */ React3.createElement("div", {
|
|
736
819
|
className: "flex flex-col gap-5 lg:gap-7"
|
|
@@ -742,7 +825,7 @@ function OmnibusDashboard({ data, initialRange, appName, surveyDrilldownHref })
|
|
|
742
825
|
className: "text-pretty text-xl font-bold tracking-tight sm:text-2xl"
|
|
743
826
|
}, "Analytics"), /* @__PURE__ */ React3.createElement("p", {
|
|
744
827
|
className: "text-muted-foreground truncate text-[13px]"
|
|
745
|
-
}, "Revenue \xB7 Attribution \xB7 Video \xB7 Traffic \xB7 Surveys
|
|
828
|
+
}, "Revenue \xB7 Attribution \xB7 Video \xB7 Traffic \xB7 Surveys, ", rangeLabel)), /* @__PURE__ */ React3.createElement("div", {
|
|
746
829
|
className: "flex shrink-0 items-center gap-2"
|
|
747
830
|
}, isPending && /* @__PURE__ */ React3.createElement("span", {
|
|
748
831
|
className: "text-muted-foreground animate-pulse text-xs"
|
|
@@ -787,12 +870,19 @@ function OmnibusDashboard({ data, initialRange, appName, surveyDrilldownHref })
|
|
|
787
870
|
value: fmtK(totalClicks),
|
|
788
871
|
sub: `${data.shortlinks.length} active \xB7 ${signupCount} signups`,
|
|
789
872
|
icon: MousePointerClickIcon
|
|
873
|
+
}), hasValuePaths && /* @__PURE__ */ React3.createElement(Stat, {
|
|
874
|
+
label: "Value Paths",
|
|
875
|
+
value: `${data.valuePaths.terminalParticipants}/${data.valuePaths.contacts}`,
|
|
876
|
+
sub: `${data.valuePaths.answerEvents} answers \xB7 ${data.valuePaths.dripEvents} drips`,
|
|
877
|
+
icon: RouteIcon
|
|
790
878
|
}), hasSurveys && /* @__PURE__ */ React3.createElement(Stat, {
|
|
791
879
|
label: "Surveys",
|
|
792
880
|
value: `${data.surveySegments.length}`,
|
|
793
881
|
sub: `${data.surveySegments.reduce((s, q) => s + q.responses, 0).toLocaleString()} responses`,
|
|
794
882
|
icon: ClipboardListIcon
|
|
795
|
-
})),
|
|
883
|
+
})), hasTraffic && /* @__PURE__ */ React3.createElement(TrafficBreakdownsCard, {
|
|
884
|
+
traffic: data.traffic
|
|
885
|
+
}), hasMux && data.mux.topVideos.length > 0 && /* @__PURE__ */ React3.createElement(TopVideosCard, {
|
|
796
886
|
label: "Site Videos",
|
|
797
887
|
subtitle: `${fmtWatchMs(data.mux.overview.totalPlayingTimeMs)} watch time \xB7 ${fmtK(data.mux.overview.uniqueViewers)} viewers`,
|
|
798
888
|
icon: FilmIcon,
|
|
@@ -834,7 +924,7 @@ function OmnibusDashboard({ data, initialRange, appName, surveyDrilldownHref })
|
|
|
834
924
|
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
835
925
|
}, "Conversion Rate"), /* @__PURE__ */ React3.createElement("span", {
|
|
836
926
|
className: "text-foreground mt-1 block text-xl font-bold tabular-nums"
|
|
837
|
-
}, signupCount > 0 ? `${(purchaseAttrCount / signupCount * 100).toFixed(1)}%` : "
|
|
927
|
+
}, signupCount > 0 ? `${(purchaseAttrCount / signupCount * 100).toFixed(1)}%` : "-"))))), hasAttributionCoverage && data.attributionCoverage.totalPurchases > 0 && /* @__PURE__ */ React3.createElement(Card, null, /* @__PURE__ */ React3.createElement(CardHeader, {
|
|
838
928
|
className: "pb-3"
|
|
839
929
|
}, /* @__PURE__ */ React3.createElement("div", {
|
|
840
930
|
className: "flex items-center gap-2.5"
|
|
@@ -866,7 +956,109 @@ function OmnibusDashboard({ data, initialRange, appName, surveyDrilldownHref })
|
|
|
866
956
|
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
867
957
|
}, "Total Purchases"), /* @__PURE__ */ React3.createElement("span", {
|
|
868
958
|
className: "text-foreground mt-1 block text-xl font-bold tabular-nums"
|
|
869
|
-
}, data.attributionCoverage.totalPurchases.toLocaleString())))
|
|
959
|
+
}, data.attributionCoverage.totalPurchases.toLocaleString()))), data.attributionCoverage.quality && /* @__PURE__ */ React3.createElement("div", {
|
|
960
|
+
className: "mt-4 grid gap-2 sm:grid-cols-4"
|
|
961
|
+
}, [
|
|
962
|
+
"strong",
|
|
963
|
+
"medium",
|
|
964
|
+
"weak",
|
|
965
|
+
"unknown"
|
|
966
|
+
].map((lane) => {
|
|
967
|
+
const item = data.attributionCoverage.quality[lane];
|
|
968
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
969
|
+
key: lane,
|
|
970
|
+
className: "rounded-lg border border-border/40 p-3"
|
|
971
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
972
|
+
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
973
|
+
}, lane), /* @__PURE__ */ React3.createElement("span", {
|
|
974
|
+
className: "text-foreground mt-1 block text-lg font-bold tabular-nums"
|
|
975
|
+
}, fmt$(item.revenue)), /* @__PURE__ */ React3.createElement("span", {
|
|
976
|
+
className: "text-muted-foreground text-[11px]"
|
|
977
|
+
}, item.purchases.toLocaleString(), " purchases \xB7", " ", (item.revenuePercent * 100).toFixed(1), "%"));
|
|
978
|
+
})))), hasValuePaths && /* @__PURE__ */ React3.createElement(Card, null, /* @__PURE__ */ React3.createElement(CardHeader, {
|
|
979
|
+
className: "pb-3"
|
|
980
|
+
}, /* @__PURE__ */ React3.createElement("div", {
|
|
981
|
+
className: "flex items-center gap-2.5"
|
|
982
|
+
}, /* @__PURE__ */ React3.createElement("div", {
|
|
983
|
+
className: "flex h-7 w-7 items-center justify-center rounded-lg bg-sky-500/10 text-sky-500"
|
|
984
|
+
}, /* @__PURE__ */ React3.createElement(RouteIcon, {
|
|
985
|
+
className: "h-3.5 w-3.5"
|
|
986
|
+
})), /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement(CardTitle, {
|
|
987
|
+
className: "text-sm font-semibold"
|
|
988
|
+
}, "Value Paths"), /* @__PURE__ */ React3.createElement(CardDescription, {
|
|
989
|
+
className: "text-[11px]"
|
|
990
|
+
}, "Progression, answer clicks, drip fallback, and terminal completion")))), /* @__PURE__ */ React3.createElement(CardContent, {
|
|
991
|
+
className: "space-y-5"
|
|
992
|
+
}, (() => {
|
|
993
|
+
const vp = data.valuePaths;
|
|
994
|
+
const completionRate = vp.contacts > 0 ? vp.terminalParticipants / vp.contacts * 100 : 0;
|
|
995
|
+
const clickRate = vp.contacts > 0 ? vp.participantsWithAnswerClicks / vp.contacts * 100 : 0;
|
|
996
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", {
|
|
997
|
+
className: "grid grid-cols-2 gap-2 sm:grid-cols-5"
|
|
998
|
+
}, /* @__PURE__ */ React3.createElement("div", {
|
|
999
|
+
className: "bg-muted/20 rounded-lg p-3"
|
|
1000
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1001
|
+
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
1002
|
+
}, "Contacts"), /* @__PURE__ */ React3.createElement("span", {
|
|
1003
|
+
className: "text-foreground mt-1 block text-lg font-bold tabular-nums"
|
|
1004
|
+
}, vp.contacts.toLocaleString())), /* @__PURE__ */ React3.createElement("div", {
|
|
1005
|
+
className: "bg-muted/20 rounded-lg p-3"
|
|
1006
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1007
|
+
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
1008
|
+
}, "Terminal"), /* @__PURE__ */ React3.createElement("span", {
|
|
1009
|
+
className: "text-foreground mt-1 block text-lg font-bold tabular-nums"
|
|
1010
|
+
}, vp.terminalParticipants.toLocaleString()), /* @__PURE__ */ React3.createElement("span", {
|
|
1011
|
+
className: "text-muted-foreground/70 text-[10px]"
|
|
1012
|
+
}, completionRate.toFixed(0), "% completed")), /* @__PURE__ */ React3.createElement("div", {
|
|
1013
|
+
className: "bg-muted/20 rounded-lg p-3"
|
|
1014
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1015
|
+
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
1016
|
+
}, "Answered"), /* @__PURE__ */ React3.createElement("span", {
|
|
1017
|
+
className: "text-foreground mt-1 block text-lg font-bold tabular-nums"
|
|
1018
|
+
}, vp.participantsWithAnswerClicks.toLocaleString()), /* @__PURE__ */ React3.createElement("span", {
|
|
1019
|
+
className: "text-muted-foreground/70 text-[10px]"
|
|
1020
|
+
}, clickRate.toFixed(0), "% clicked")), /* @__PURE__ */ React3.createElement("div", {
|
|
1021
|
+
className: "bg-muted/20 rounded-lg p-3"
|
|
1022
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1023
|
+
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
1024
|
+
}, "Drips"), /* @__PURE__ */ React3.createElement("span", {
|
|
1025
|
+
className: "text-foreground mt-1 block text-lg font-bold tabular-nums"
|
|
1026
|
+
}, vp.dripEvents.toLocaleString())), /* @__PURE__ */ React3.createElement("div", {
|
|
1027
|
+
className: "bg-muted/20 rounded-lg p-3"
|
|
1028
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1029
|
+
className: "text-muted-foreground block text-[11px] font-medium uppercase tracking-wider"
|
|
1030
|
+
}, "Blocked"), /* @__PURE__ */ React3.createElement("span", {
|
|
1031
|
+
className: "text-foreground mt-1 block text-lg font-bold tabular-nums"
|
|
1032
|
+
}, vp.blockedIntents.toLocaleString()))), vp.answerOptions.length > 0 && /* @__PURE__ */ React3.createElement("div", {
|
|
1033
|
+
className: "space-y-2"
|
|
1034
|
+
}, /* @__PURE__ */ React3.createElement("p", {
|
|
1035
|
+
className: "text-muted-foreground text-[11px]"
|
|
1036
|
+
}, "Top answer choices by captured answer event"), /* @__PURE__ */ React3.createElement("div", {
|
|
1037
|
+
className: "space-y-1.5"
|
|
1038
|
+
}, vp.answerOptions.slice(0, 8).map((answer) => {
|
|
1039
|
+
const pct = vp.answerEvents > 0 ? answer.count / vp.answerEvents * 100 : 0;
|
|
1040
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
1041
|
+
key: answer.key,
|
|
1042
|
+
className: "flex items-center gap-2.5"
|
|
1043
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1044
|
+
className: "text-muted-foreground w-[140px] shrink-0 truncate text-right text-[12px]",
|
|
1045
|
+
title: answer.key
|
|
1046
|
+
}, answer.optionValue), /* @__PURE__ */ React3.createElement("div", {
|
|
1047
|
+
className: "bg-muted/50 relative h-5 flex-1 overflow-hidden rounded"
|
|
1048
|
+
}, /* @__PURE__ */ React3.createElement("div", {
|
|
1049
|
+
className: "absolute inset-y-0 left-0 rounded bg-sky-500/20",
|
|
1050
|
+
style: {
|
|
1051
|
+
width: `${Math.max(pct, 1)}%`
|
|
1052
|
+
}
|
|
1053
|
+
}), /* @__PURE__ */ React3.createElement("div", {
|
|
1054
|
+
className: "relative flex h-full items-center px-2"
|
|
1055
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
1056
|
+
className: "text-foreground/70 text-[11px] font-medium tabular-nums"
|
|
1057
|
+
}, pct.toFixed(0), "%"))), /* @__PURE__ */ React3.createElement("span", {
|
|
1058
|
+
className: "text-muted-foreground w-10 shrink-0 text-right text-[11px] tabular-nums"
|
|
1059
|
+
}, answer.count.toLocaleString()));
|
|
1060
|
+
}))));
|
|
1061
|
+
})())), hasSurveys && /* @__PURE__ */ React3.createElement(Card, null, /* @__PURE__ */ React3.createElement(CardHeader, {
|
|
870
1062
|
className: "pb-3"
|
|
871
1063
|
}, /* @__PURE__ */ React3.createElement("div", {
|
|
872
1064
|
className: "flex items-center justify-between"
|
|
@@ -1238,13 +1430,13 @@ function OmnibusDashboard({ data, initialRange, appName, surveyDrilldownHref })
|
|
|
1238
1430
|
className: `py-2.5 pr-4 text-right text-sm font-semibold tabular-nums ${p.totalAmount > 0 ? "text-emerald-600 dark:text-emerald-400" : "text-muted-foreground"}`
|
|
1239
1431
|
}, p.totalAmount > 0 ? fmt$(p.totalAmount) : "Free"), /* @__PURE__ */ React3.createElement("td", {
|
|
1240
1432
|
className: "py-2.5 pr-4 text-right text-sm tabular-nums"
|
|
1241
|
-
}, p.seats ?? "
|
|
1433
|
+
}, p.seats ?? "-"), /* @__PURE__ */ React3.createElement("td", {
|
|
1242
1434
|
className: "max-w-[200px] truncate py-2.5 pr-4 text-sm font-medium"
|
|
1243
1435
|
}, p.productName), /* @__PURE__ */ React3.createElement("td", {
|
|
1244
1436
|
className: "text-muted-foreground hidden max-w-[150px] truncate py-2.5 pr-4 text-sm sm:table-cell"
|
|
1245
|
-
}, p.userName ?? p.userEmail ?? "
|
|
1437
|
+
}, p.userName ?? p.userEmail ?? "-"), /* @__PURE__ */ React3.createElement("td", {
|
|
1246
1438
|
className: "text-muted-foreground hidden py-2.5 pr-4 text-sm sm:table-cell"
|
|
1247
|
-
}, p.country ? `${countryFlag2(p.country)} ${p.country}` : "
|
|
1439
|
+
}, p.country ? `${countryFlag2(p.country)} ${p.country}` : "-"), /* @__PURE__ */ React3.createElement("td", {
|
|
1248
1440
|
className: "text-muted-foreground whitespace-nowrap py-2.5 pr-4 text-sm"
|
|
1249
1441
|
}, fmtAgo(p.createdAt)))))))))));
|
|
1250
1442
|
}
|