@handled-ai/design-system 0.8.0 → 0.9.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/README.md +14 -4
- package/dist/charts/bar-chart-component.d.ts +24 -0
- package/dist/charts/bar-chart-component.js +123 -0
- package/dist/charts/bar-chart-component.js.map +1 -0
- package/dist/charts/chart-tooltip.d.ts +26 -0
- package/dist/charts/chart-tooltip.js +69 -0
- package/dist/charts/chart-tooltip.js.map +1 -0
- package/dist/charts/chart.d.ts +64 -0
- package/dist/charts/chart.js +285 -0
- package/dist/charts/chart.js.map +1 -0
- package/dist/charts/donut-chart.d.ts +21 -0
- package/dist/charts/donut-chart.js +96 -0
- package/dist/charts/donut-chart.js.map +1 -0
- package/dist/charts/index.d.ts +11 -0
- package/dist/charts/index.js +10 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/pipeline-overview.d.ts +76 -0
- package/dist/charts/pipeline-overview.js +372 -0
- package/dist/charts/pipeline-overview.js.map +1 -0
- package/dist/charts/sankey-chart.d.ts +52 -0
- package/dist/charts/sankey-chart.js +219 -0
- package/dist/charts/sankey-chart.js.map +1 -0
- package/dist/charts/top-line-metrics.d.ts +26 -0
- package/dist/charts/top-line-metrics.js +224 -0
- package/dist/charts/top-line-metrics.js.map +1 -0
- package/dist/charts/trend-area-chart.d.ts +21 -0
- package/dist/charts/trend-area-chart.js +150 -0
- package/dist/charts/trend-area-chart.js.map +1 -0
- package/dist/charts/volume-analysis-chart.d.ts +19 -0
- package/dist/charts/volume-analysis-chart.js +121 -0
- package/dist/charts/volume-analysis-chart.js.map +1 -0
- package/dist/components/activity-detail.d.ts +38 -0
- package/dist/components/activity-detail.js +163 -0
- package/dist/components/activity-detail.js.map +1 -0
- package/dist/components/activity-log.d.ts +21 -0
- package/dist/components/activity-log.js +61 -0
- package/dist/components/activity-log.js.map +1 -0
- package/dist/components/agent-popover.d.ts +71 -0
- package/dist/components/agent-popover.js +282 -0
- package/dist/components/agent-popover.js.map +1 -0
- package/dist/components/agent-widget.d.ts +24 -0
- package/dist/components/agent-widget.js +117 -0
- package/dist/components/agent-widget.js.map +1 -0
- package/dist/components/avatar.d.ts +13 -0
- package/dist/components/avatar.js +140 -0
- package/dist/components/avatar.js.map +1 -0
- package/dist/components/badge.d.ts +12 -0
- package/dist/components/badge.js +75 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/button.d.ts +13 -0
- package/dist/components/button.js +83 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/card.d.ts +11 -0
- package/dist/components/card.js +119 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/contact-list.d.ts +34 -0
- package/dist/components/contact-list.js +84 -0
- package/dist/components/contact-list.js.map +1 -0
- package/dist/components/dashboard-cards.d.ts +10 -0
- package/dist/components/dashboard-cards.js +164 -0
- package/dist/components/dashboard-cards.js.map +1 -0
- package/dist/components/data-table-display.d.ts +19 -0
- package/dist/components/data-table-display.js +109 -0
- package/dist/components/data-table-display.js.map +1 -0
- package/dist/components/data-table-filter.d.ts +18 -0
- package/dist/components/data-table-filter.js +107 -0
- package/dist/components/data-table-filter.js.map +1 -0
- package/dist/components/data-table-quick-views.d.ts +13 -0
- package/dist/components/data-table-quick-views.js +90 -0
- package/dist/components/data-table-quick-views.js.map +1 -0
- package/dist/components/data-table-toolbar.d.ts +18 -0
- package/dist/components/data-table-toolbar.js +45 -0
- package/dist/components/data-table-toolbar.js.map +1 -0
- package/dist/components/data-table.d.ts +39 -0
- package/dist/components/data-table.js +821 -0
- package/dist/components/data-table.js.map +1 -0
- package/dist/components/detail-view.d.ts +44 -0
- package/dist/components/detail-view.js +165 -0
- package/dist/components/detail-view.js.map +1 -0
- package/dist/components/dialog.d.ts +19 -0
- package/dist/components/dialog.js +188 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/dropdown-menu.d.ts +27 -0
- package/dist/components/dropdown-menu.js +279 -0
- package/dist/components/dropdown-menu.js.map +1 -0
- package/dist/components/entity-panel.d.ts +69 -0
- package/dist/components/entity-panel.js +584 -0
- package/dist/components/entity-panel.js.map +1 -0
- package/dist/components/inbox-row.d.ts +27 -0
- package/dist/components/inbox-row.js +139 -0
- package/dist/components/inbox-row.js.map +1 -0
- package/dist/components/inbox-toolbar.d.ts +21 -0
- package/dist/components/inbox-toolbar.js +203 -0
- package/dist/components/inbox-toolbar.js.map +1 -0
- package/dist/components/input.d.ts +5 -0
- package/dist/components/input.js +50 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/insights-filter-bar.d.ts +21 -0
- package/dist/components/insights-filter-bar.js +99 -0
- package/dist/components/insights-filter-bar.js.map +1 -0
- package/dist/components/item-list-display.d.ts +22 -0
- package/dist/components/item-list-display.js +240 -0
- package/dist/components/item-list-display.js.map +1 -0
- package/dist/components/item-list-filter.d.ts +16 -0
- package/dist/components/item-list-filter.js +87 -0
- package/dist/components/item-list-filter.js.map +1 -0
- package/dist/components/item-list-toolbar.d.ts +25 -0
- package/dist/components/item-list-toolbar.js +79 -0
- package/dist/components/item-list-toolbar.js.map +1 -0
- package/dist/components/item-list.d.ts +20 -0
- package/dist/components/item-list.js +702 -0
- package/dist/components/item-list.js.map +1 -0
- package/dist/components/label.d.ts +6 -0
- package/dist/components/label.js +55 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/message.d.ts +23 -0
- package/dist/components/message.js +117 -0
- package/dist/components/message.js.map +1 -0
- package/dist/components/metric-card.d.ts +25 -0
- package/dist/components/metric-card.js +107 -0
- package/dist/components/metric-card.js.map +1 -0
- package/dist/components/performance-metrics-table.d.ts +38 -0
- package/dist/components/performance-metrics-table.js +342 -0
- package/dist/components/performance-metrics-table.js.map +1 -0
- package/dist/components/preview-list.d.ts +14 -0
- package/dist/components/preview-list.js +83 -0
- package/dist/components/preview-list.js.map +1 -0
- package/dist/components/progress.d.ts +6 -0
- package/dist/components/progress.js +69 -0
- package/dist/components/progress.js.map +1 -0
- package/dist/components/quick-action-chat-area.d.ts +24 -0
- package/dist/components/quick-action-chat-area.js +178 -0
- package/dist/components/quick-action-chat-area.js.map +1 -0
- package/dist/components/quick-action-modal.d.ts +30 -0
- package/dist/components/quick-action-modal.js +288 -0
- package/dist/components/quick-action-modal.js.map +1 -0
- package/dist/components/quick-action-sidebar-nav.d.ts +51 -0
- package/dist/components/quick-action-sidebar-nav.js +528 -0
- package/dist/components/quick-action-sidebar-nav.js.map +1 -0
- package/dist/components/recommended-actions-section.d.ts +23 -0
- package/dist/components/recommended-actions-section.js +215 -0
- package/dist/components/recommended-actions-section.js.map +1 -0
- package/dist/components/report-card.d.ts +26 -0
- package/dist/components/report-card.js +69 -0
- package/dist/components/report-card.js.map +1 -0
- package/dist/components/score-analysis-modal.d.ts +26 -0
- package/dist/components/score-analysis-modal.js +141 -0
- package/dist/components/score-analysis-modal.js.map +1 -0
- package/dist/components/score-breakdown.d.ts +17 -0
- package/dist/components/score-breakdown.js +162 -0
- package/dist/components/score-breakdown.js.map +1 -0
- package/dist/components/score-feedback.d.ts +40 -0
- package/dist/components/score-feedback.js +209 -0
- package/dist/components/score-feedback.js.map +1 -0
- package/dist/components/score-ring.d.ts +14 -0
- package/dist/components/score-ring.js +79 -0
- package/dist/components/score-ring.js.map +1 -0
- package/dist/components/scroll-area.d.ts +7 -0
- package/dist/components/scroll-area.js +101 -0
- package/dist/components/scroll-area.js.map +1 -0
- package/dist/components/select.d.ts +17 -0
- package/dist/components/select.js +228 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.d.ts +6 -0
- package/dist/components/separator.js +61 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/sheet.d.ts +16 -0
- package/dist/components/sheet.js +168 -0
- package/dist/components/sheet.js.map +1 -0
- package/dist/components/sidebar.d.ts +73 -0
- package/dist/components/sidebar.js +723 -0
- package/dist/components/sidebar.js.map +1 -0
- package/dist/components/signal-feedback-inline.d.ts +51 -0
- package/dist/components/signal-feedback-inline.js +548 -0
- package/dist/components/signal-feedback-inline.js.map +1 -0
- package/dist/components/simple-data-table.d.ts +15 -0
- package/dist/components/simple-data-table.js +91 -0
- package/dist/components/simple-data-table.js.map +1 -0
- package/dist/components/skeleton.d.ts +5 -0
- package/dist/components/skeleton.js +44 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/status-badge.d.ts +10 -0
- package/dist/components/status-badge.js +82 -0
- package/dist/components/status-badge.js.map +1 -0
- package/dist/components/styled-bar-list.d.ts +20 -0
- package/dist/components/styled-bar-list.js +59 -0
- package/dist/components/styled-bar-list.js.map +1 -0
- package/dist/components/suggested-actions.d.ts +110 -0
- package/dist/components/suggested-actions.js +1538 -0
- package/dist/components/suggested-actions.js.map +1 -0
- package/dist/components/table.d.ts +12 -0
- package/dist/components/table.js +147 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.d.ts +14 -0
- package/dist/components/tabs.js +129 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/textarea.d.ts +5 -0
- package/dist/components/textarea.js +47 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/components/timeline-activity.d.ts +34 -0
- package/dist/components/timeline-activity.js +181 -0
- package/dist/components/timeline-activity.js.map +1 -0
- package/dist/components/tooltip.d.ts +9 -0
- package/dist/components/tooltip.js +93 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/components/view-mode-toggle.d.ts +16 -0
- package/dist/components/view-mode-toggle.js +24 -0
- package/dist/components/view-mode-toggle.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +21 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +68 -1878
- package/dist/index.js +69 -10918
- package/dist/index.js.map +1 -1
- package/dist/lib/icons.d.ts +18 -0
- package/dist/lib/icons.js +21 -0
- package/dist/lib/icons.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/prototype/index.d.ts +20 -0
- package/dist/prototype/index.js +8 -0
- package/dist/prototype/index.js.map +1 -0
- package/dist/prototype/prototype-accounts-view.d.ts +22 -0
- package/dist/prototype/prototype-accounts-view.js +70 -0
- package/dist/prototype/prototype-accounts-view.js.map +1 -0
- package/dist/prototype/prototype-admin-view.d.ts +21 -0
- package/dist/prototype/prototype-admin-view.js +53 -0
- package/dist/prototype/prototype-admin-view.js.map +1 -0
- package/dist/prototype/prototype-config.d.ts +226 -0
- package/dist/prototype/prototype-config.js +1 -0
- package/dist/prototype/prototype-config.js.map +1 -0
- package/dist/prototype/prototype-inbox-view.d.ts +48 -0
- package/dist/prototype/prototype-inbox-view.js +701 -0
- package/dist/prototype/prototype-inbox-view.js.map +1 -0
- package/dist/prototype/prototype-insights-view.d.ts +23 -0
- package/dist/prototype/prototype-insights-view.js +335 -0
- package/dist/prototype/prototype-insights-view.js.map +1 -0
- package/dist/prototype/prototype-shell.d.ts +40 -0
- package/dist/prototype/prototype-shell.js +190 -0
- package/dist/prototype/prototype-shell.js.map +1 -0
- package/dist/prototype/prototype-work-queue-view.d.ts +8 -0
- package/dist/prototype/prototype-work-queue-view.js +17 -0
- package/dist/prototype/prototype-work-queue-view.js.map +1 -0
- package/dist/three/agent-orb.d.ts +39 -0
- package/dist/three/agent-orb.js +500 -0
- package/dist/three/agent-orb.js.map +1 -0
- package/dist/three/index.d.ts +2 -0
- package/dist/three/index.js +2 -0
- package/dist/three/index.js.map +1 -0
- package/package.json +98 -17
- package/src/charts/bar-chart-component.tsx +150 -0
- package/src/charts/chart-tooltip.tsx +86 -0
- package/src/charts/chart.tsx +371 -0
- package/src/charts/donut-chart.tsx +112 -0
- package/src/charts/index.ts +13 -0
- package/src/charts/pipeline-overview.tsx +476 -0
- package/src/charts/sankey-chart.tsx +290 -0
- package/src/charts/top-line-metrics.tsx +261 -0
- package/src/charts/trend-area-chart.tsx +150 -0
- package/src/charts/volume-analysis-chart.tsx +124 -0
- package/src/components/activity-detail.tsx +233 -0
- package/src/components/activity-log.tsx +89 -0
- package/src/components/agent-popover.tsx +373 -0
- package/src/components/agent-widget.tsx +163 -0
- package/src/components/avatar.tsx +109 -0
- package/src/components/badge.tsx +48 -0
- package/src/components/button.tsx +59 -0
- package/src/components/card.tsx +92 -0
- package/src/components/contact-list.tsx +121 -0
- package/src/components/dashboard-cards.tsx +170 -0
- package/src/components/data-table-display.tsx +139 -0
- package/src/components/data-table-filter.tsx +138 -0
- package/src/components/data-table-quick-views.tsx +103 -0
- package/src/components/data-table-toolbar.tsx +56 -0
- package/src/components/data-table.tsx +915 -0
- package/src/components/detail-view.tsx +237 -0
- package/src/components/dialog.tsx +158 -0
- package/src/components/dropdown-menu.tsx +257 -0
- package/src/components/entity-panel.tsx +767 -0
- package/src/components/inbox-row.tsx +132 -0
- package/src/components/inbox-toolbar.tsx +213 -0
- package/src/components/input.tsx +21 -0
- package/src/components/insights-filter-bar.tsx +132 -0
- package/src/components/item-list-display.tsx +278 -0
- package/src/components/item-list-filter.tsx +118 -0
- package/src/components/item-list-toolbar.tsx +97 -0
- package/src/components/item-list.tsx +843 -0
- package/src/components/label.tsx +24 -0
- package/src/components/message.tsx +83 -0
- package/src/components/metric-card.tsx +178 -0
- package/src/components/performance-metrics-table.tsx +442 -0
- package/src/components/preview-list.tsx +62 -0
- package/src/components/progress.tsx +31 -0
- package/src/components/quick-action-chat-area.tsx +156 -0
- package/src/components/quick-action-modal.tsx +331 -0
- package/src/components/quick-action-sidebar-nav.tsx +592 -0
- package/src/components/recommended-actions-section.tsx +258 -0
- package/src/components/report-card.tsx +106 -0
- package/src/components/score-analysis-modal.tsx +172 -0
- package/src/components/score-breakdown.tsx +179 -0
- package/src/components/score-feedback.tsx +288 -0
- package/src/components/score-ring.tsx +87 -0
- package/src/components/scroll-area.tsx +58 -0
- package/src/components/select.tsx +190 -0
- package/src/components/separator.tsx +28 -0
- package/src/components/sheet.tsx +143 -0
- package/src/components/sidebar.tsx +726 -0
- package/src/components/signal-feedback-inline.tsx +591 -0
- package/src/components/simple-data-table.tsx +124 -0
- package/src/components/skeleton.tsx +15 -0
- package/src/components/status-badge.tsx +63 -0
- package/src/components/styled-bar-list.tsx +70 -0
- package/src/components/suggested-actions.tsx +1985 -0
- package/src/components/table.tsx +116 -0
- package/src/components/tabs.tsx +91 -0
- package/src/components/textarea.tsx +18 -0
- package/src/components/timeline-activity.tsx +234 -0
- package/src/components/tooltip.tsx +57 -0
- package/src/components/view-mode-toggle.tsx +39 -0
- package/src/hooks/use-mobile.ts +21 -0
- package/src/index.ts +77 -0
- package/src/lib/icons.ts +18 -0
- package/src/lib/utils.ts +6 -0
- package/src/prototype/index.ts +11 -0
- package/src/prototype/prototype-accounts-view.tsx +112 -0
- package/src/prototype/prototype-admin-view.tsx +67 -0
- package/src/prototype/prototype-config.ts +243 -0
- package/src/prototype/prototype-inbox-view.tsx +810 -0
- package/src/prototype/prototype-insights-view.tsx +379 -0
- package/src/prototype/prototype-shell.tsx +219 -0
- package/src/prototype/prototype-work-queue-view.tsx +30 -0
- package/src/styles/globals.css +299 -0
- package/src/three/agent-orb.tsx +557 -0
- package/src/three/index.ts +5 -0
- package/src/types/r3f.d.ts +8 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
"use client";
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __defProps = Object.defineProperties;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24
|
+
import * as React from "react";
|
|
25
|
+
import {
|
|
26
|
+
CheckSquare,
|
|
27
|
+
Clock,
|
|
28
|
+
DollarSign,
|
|
29
|
+
HelpCircle,
|
|
30
|
+
MessageSquare,
|
|
31
|
+
SkipForward,
|
|
32
|
+
ThumbsDown,
|
|
33
|
+
ThumbsUp,
|
|
34
|
+
Users,
|
|
35
|
+
X
|
|
36
|
+
} from "lucide-react";
|
|
37
|
+
import { Badge } from "./badge.js";
|
|
38
|
+
import { Button } from "./button.js";
|
|
39
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./tooltip.js";
|
|
40
|
+
function getCategoryBadgeClass(category) {
|
|
41
|
+
if (category === "Churn") return "bg-white text-black border-red-300";
|
|
42
|
+
if (category === "Expand") return "bg-green-100 text-green-800 border-green-200";
|
|
43
|
+
if (category === "Nurture") return "bg-blue-100 text-blue-800 border-blue-200";
|
|
44
|
+
return "bg-muted text-muted-foreground border-border";
|
|
45
|
+
}
|
|
46
|
+
function getPriorityBadgeClass(priority) {
|
|
47
|
+
if (priority === "High") return "border-foreground text-foreground";
|
|
48
|
+
if (priority === "Medium") return "border-muted-foreground text-muted-foreground";
|
|
49
|
+
return "border-border text-muted-foreground";
|
|
50
|
+
}
|
|
51
|
+
function RecommendedActionsSection({
|
|
52
|
+
actions,
|
|
53
|
+
title = "Recommended Actions",
|
|
54
|
+
onQueueAction,
|
|
55
|
+
onDismissAction,
|
|
56
|
+
onFeedback
|
|
57
|
+
}) {
|
|
58
|
+
const [dismissedActions, setDismissedActions] = React.useState(/* @__PURE__ */ new Set());
|
|
59
|
+
const [actionFeedback, setActionFeedback] = React.useState({});
|
|
60
|
+
const [feedbackComment, setFeedbackComment] = React.useState({});
|
|
61
|
+
const [commentOpen, setCommentOpen] = React.useState({});
|
|
62
|
+
const visibleActions = actions.filter((action) => !dismissedActions.has(action.id));
|
|
63
|
+
const handleDismissAction = (action) => {
|
|
64
|
+
setDismissedActions((previous) => /* @__PURE__ */ new Set([...previous, action.id]));
|
|
65
|
+
onDismissAction == null ? void 0 : onDismissAction(action);
|
|
66
|
+
};
|
|
67
|
+
const handleFeedback = (actionId, feedback) => {
|
|
68
|
+
setActionFeedback((previous) => __spreadProps(__spreadValues({}, previous), { [actionId]: feedback }));
|
|
69
|
+
setCommentOpen((previous) => __spreadProps(__spreadValues({}, previous), { [actionId]: true }));
|
|
70
|
+
};
|
|
71
|
+
const submitFeedback = (actionId) => {
|
|
72
|
+
var _a, _b;
|
|
73
|
+
const feedback = actionFeedback[actionId];
|
|
74
|
+
if (!feedback) return;
|
|
75
|
+
onFeedback == null ? void 0 : onFeedback(actionId, feedback, (_b = (_a = feedbackComment[actionId]) == null ? void 0 : _a.trim()) != null ? _b : "");
|
|
76
|
+
setCommentOpen((previous) => __spreadProps(__spreadValues({}, previous), { [actionId]: false }));
|
|
77
|
+
setFeedbackComment((previous) => __spreadProps(__spreadValues({}, previous), { [actionId]: "" }));
|
|
78
|
+
};
|
|
79
|
+
return /* @__PURE__ */ jsxs("section", { className: "border-t border-border py-6", children: [
|
|
80
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 flex items-center justify-between", children: [
|
|
81
|
+
/* @__PURE__ */ jsx("h3", { className: "text-[11px] font-bold uppercase tracking-wider text-muted-foreground/70", children: title }),
|
|
82
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
83
|
+
visibleActions.length,
|
|
84
|
+
" actions"
|
|
85
|
+
] })
|
|
86
|
+
] }),
|
|
87
|
+
visibleActions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed border-border p-4 text-sm text-muted-foreground", children: "All recommended actions are dismissed." }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: visibleActions.map((action) => {
|
|
88
|
+
var _a, _b, _c, _d;
|
|
89
|
+
return /* @__PURE__ */ jsxs(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
className: "group rounded-md border border-border bg-background p-4 transition-colors hover:bg-muted/20",
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-start justify-between gap-3", children: [
|
|
95
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
96
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium leading-snug text-foreground", children: action.title }),
|
|
97
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
98
|
+
/* @__PURE__ */ jsx(Badge, { variant: "outline", className: `px-2.5 py-1 text-xs font-medium ${getCategoryBadgeClass(action.category)}`, children: (_a = action.category) != null ? _a : "General" }),
|
|
99
|
+
/* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
100
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: `cursor-help px-2.5 py-1 text-xs ${getPriorityBadgeClass(action.priority)}`, children: [
|
|
101
|
+
/* @__PURE__ */ jsx(DollarSign, { className: "mr-1 h-3 w-3" }),
|
|
102
|
+
(_b = action.priority) != null ? _b : "Medium",
|
|
103
|
+
/* @__PURE__ */ jsx(HelpCircle, { className: "ml-1 h-3 w-3" })
|
|
104
|
+
] }) }),
|
|
105
|
+
/* @__PURE__ */ jsx(TooltipContent, { className: "max-w-xs", children: /* @__PURE__ */ jsx("p", { className: "text-xs leading-relaxed", children: action.confidence ? `${Math.round(action.confidence * 100)}% confidence based on current account signals.` : "Priority reflects expected impact and urgency." }) })
|
|
106
|
+
] }) }),
|
|
107
|
+
typeof action.revenueImpact === "number" && /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
108
|
+
"+$",
|
|
109
|
+
action.revenueImpact.toLocaleString(),
|
|
110
|
+
"/mo impact"
|
|
111
|
+
] })
|
|
112
|
+
] })
|
|
113
|
+
] }),
|
|
114
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
Button,
|
|
117
|
+
{
|
|
118
|
+
variant: "ghost",
|
|
119
|
+
size: "icon",
|
|
120
|
+
className: "h-8 w-8 bg-foreground text-background hover:bg-foreground/90",
|
|
121
|
+
onClick: () => onQueueAction == null ? void 0 : onQueueAction(action),
|
|
122
|
+
children: /* @__PURE__ */ jsx(CheckSquare, { className: "h-4 w-4" })
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
Button,
|
|
127
|
+
{
|
|
128
|
+
variant: "ghost",
|
|
129
|
+
size: "icon",
|
|
130
|
+
className: "h-8 w-8 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
131
|
+
onClick: () => handleDismissAction(action),
|
|
132
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
] })
|
|
136
|
+
] }),
|
|
137
|
+
/* @__PURE__ */ jsx("p", { className: "mb-3 text-sm leading-relaxed text-muted-foreground", children: action.reason }),
|
|
138
|
+
action.signals && action.signals.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex flex-wrap gap-1.5", children: action.signals.map((signal) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-[10px]", children: signal }, `${action.id}-${signal}`)) }),
|
|
139
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
140
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: (_c = action.dueDate) != null ? _c : "This week" }),
|
|
141
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5", children: /* @__PURE__ */ jsxs(TooltipProvider, { delayDuration: 200, children: [
|
|
142
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
143
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", children: /* @__PURE__ */ jsx(SkipForward, { className: "h-3.5 w-3.5" }) }) }),
|
|
144
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: "Skip" })
|
|
145
|
+
] }),
|
|
146
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
147
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", children: /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5" }) }) }),
|
|
148
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: "Snooze" })
|
|
149
|
+
] }),
|
|
150
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
151
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", children: /* @__PURE__ */ jsx(Users, { className: "h-3.5 w-3.5" }) }) }),
|
|
152
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: "Delegate" })
|
|
153
|
+
] }),
|
|
154
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
155
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", children: /* @__PURE__ */ jsx(MessageSquare, { className: "h-3.5 w-3.5" }) }) }),
|
|
156
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: "Add comment" })
|
|
157
|
+
] })
|
|
158
|
+
] }) })
|
|
159
|
+
] }),
|
|
160
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 border-t border-border/50 pt-3", children: [
|
|
161
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
162
|
+
/* @__PURE__ */ jsxs(
|
|
163
|
+
Button,
|
|
164
|
+
{
|
|
165
|
+
variant: "outline",
|
|
166
|
+
size: "sm",
|
|
167
|
+
className: `h-7 text-xs ${actionFeedback[action.id] === "useful" ? "border-emerald-200 bg-emerald-50 text-emerald-700" : ""}`,
|
|
168
|
+
onClick: () => handleFeedback(action.id, "useful"),
|
|
169
|
+
children: [
|
|
170
|
+
/* @__PURE__ */ jsx(ThumbsUp, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
171
|
+
"Helpful"
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsxs(
|
|
176
|
+
Button,
|
|
177
|
+
{
|
|
178
|
+
variant: "outline",
|
|
179
|
+
size: "sm",
|
|
180
|
+
className: `h-7 text-xs ${actionFeedback[action.id] === "not_useful" ? "border-red-200 bg-red-50 text-red-700" : ""}`,
|
|
181
|
+
onClick: () => handleFeedback(action.id, "not_useful"),
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ jsx(ThumbsDown, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
184
|
+
"Not helpful"
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
] }),
|
|
189
|
+
commentOpen[action.id] && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex gap-2", children: [
|
|
190
|
+
/* @__PURE__ */ jsx(
|
|
191
|
+
"input",
|
|
192
|
+
{
|
|
193
|
+
type: "text",
|
|
194
|
+
value: (_d = feedbackComment[action.id]) != null ? _d : "",
|
|
195
|
+
onChange: (event) => setFeedbackComment((previous) => __spreadProps(__spreadValues({}, previous), {
|
|
196
|
+
[action.id]: event.target.value
|
|
197
|
+
})),
|
|
198
|
+
placeholder: "Optional context for this feedback",
|
|
199
|
+
className: "h-8 flex-1 rounded-md border border-border bg-background px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring"
|
|
200
|
+
}
|
|
201
|
+
),
|
|
202
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", className: "h-8 text-xs", onClick: () => submitFeedback(action.id), children: "Submit" })
|
|
203
|
+
] })
|
|
204
|
+
] })
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
action.id
|
|
208
|
+
);
|
|
209
|
+
}) })
|
|
210
|
+
] });
|
|
211
|
+
}
|
|
212
|
+
export {
|
|
213
|
+
RecommendedActionsSection
|
|
214
|
+
};
|
|
215
|
+
//# sourceMappingURL=recommended-actions-section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/recommended-actions-section.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n CheckSquare,\n Clock,\n DollarSign,\n HelpCircle,\n MessageSquare,\n SkipForward,\n ThumbsDown,\n ThumbsUp,\n Users,\n X,\n} from \"lucide-react\"\nimport { Badge } from \"./badge\"\nimport { Button } from \"./button\"\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\"\n\nexport interface RecommendedAction {\n id: string\n title: string\n reason: string\n category?: \"Churn\" | \"Expand\" | \"Nurture\" | string\n priority?: \"High\" | \"Medium\" | \"Low\" | string\n dueDate?: string\n confidence?: number\n signals?: string[]\n revenueImpact?: number\n}\n\ninterface RecommendedActionsSectionProps {\n actions: RecommendedAction[]\n title?: string\n onQueueAction?: (action: RecommendedAction) => void\n onDismissAction?: (action: RecommendedAction) => void\n onFeedback?: (actionId: string, feedback: \"useful\" | \"not_useful\", comment: string) => void\n}\n\nfunction getCategoryBadgeClass(category?: string) {\n if (category === \"Churn\") return \"bg-white text-black border-red-300\"\n if (category === \"Expand\") return \"bg-green-100 text-green-800 border-green-200\"\n if (category === \"Nurture\") return \"bg-blue-100 text-blue-800 border-blue-200\"\n return \"bg-muted text-muted-foreground border-border\"\n}\n\nfunction getPriorityBadgeClass(priority?: string) {\n if (priority === \"High\") return \"border-foreground text-foreground\"\n if (priority === \"Medium\") return \"border-muted-foreground text-muted-foreground\"\n return \"border-border text-muted-foreground\"\n}\n\nexport function RecommendedActionsSection({\n actions,\n title = \"Recommended Actions\",\n onQueueAction,\n onDismissAction,\n onFeedback,\n}: RecommendedActionsSectionProps) {\n const [dismissedActions, setDismissedActions] = React.useState<Set<string>>(new Set())\n const [actionFeedback, setActionFeedback] = React.useState<Record<string, \"useful\" | \"not_useful\" | null>>({})\n const [feedbackComment, setFeedbackComment] = React.useState<Record<string, string>>({})\n const [commentOpen, setCommentOpen] = React.useState<Record<string, boolean>>({})\n\n const visibleActions = actions.filter((action) => !dismissedActions.has(action.id))\n\n const handleDismissAction = (action: RecommendedAction) => {\n setDismissedActions((previous) => new Set([...previous, action.id]))\n onDismissAction?.(action)\n }\n\n const handleFeedback = (actionId: string, feedback: \"useful\" | \"not_useful\") => {\n setActionFeedback((previous) => ({ ...previous, [actionId]: feedback }))\n setCommentOpen((previous) => ({ ...previous, [actionId]: true }))\n }\n\n const submitFeedback = (actionId: string) => {\n const feedback = actionFeedback[actionId]\n if (!feedback) return\n\n onFeedback?.(actionId, feedback, feedbackComment[actionId]?.trim() ?? \"\")\n setCommentOpen((previous) => ({ ...previous, [actionId]: false }))\n setFeedbackComment((previous) => ({ ...previous, [actionId]: \"\" }))\n }\n\n return (\n <section className=\"border-t border-border py-6\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h3 className=\"text-[11px] font-bold uppercase tracking-wider text-muted-foreground/70\">{title}</h3>\n <span className=\"text-xs text-muted-foreground\">{visibleActions.length} actions</span>\n </div>\n\n {visibleActions.length === 0 ? (\n <div className=\"rounded-md border border-dashed border-border p-4 text-sm text-muted-foreground\">\n All recommended actions are dismissed.\n </div>\n ) : (\n <div className=\"space-y-3\">\n {visibleActions.map((action) => (\n <div\n key={action.id}\n className=\"group rounded-md border border-border bg-background p-4 transition-colors hover:bg-muted/20\"\n >\n <div className=\"mb-3 flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1 space-y-2\">\n <h4 className=\"text-sm font-medium leading-snug text-foreground\">{action.title}</h4>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\" className={`px-2.5 py-1 text-xs font-medium ${getCategoryBadgeClass(action.category)}`}>\n {action.category ?? \"General\"}\n </Badge>\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Badge variant=\"outline\" className={`cursor-help px-2.5 py-1 text-xs ${getPriorityBadgeClass(action.priority)}`}>\n <DollarSign className=\"mr-1 h-3 w-3\" />\n {action.priority ?? \"Medium\"}\n <HelpCircle className=\"ml-1 h-3 w-3\" />\n </Badge>\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs\">\n <p className=\"text-xs leading-relaxed\">\n {action.confidence\n ? `${Math.round(action.confidence * 100)}% confidence based on current account signals.`\n : \"Priority reflects expected impact and urgency.\"}\n </p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n {typeof action.revenueImpact === \"number\" && (\n <span className=\"text-xs font-medium text-muted-foreground\">\n +${action.revenueImpact.toLocaleString()}/mo impact\n </span>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 bg-foreground text-background hover:bg-foreground/90\"\n onClick={() => onQueueAction?.(action)}\n >\n <CheckSquare className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={() => handleDismissAction(action)}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n <p className=\"mb-3 text-sm leading-relaxed text-muted-foreground\">{action.reason}</p>\n\n {action.signals && action.signals.length > 0 && (\n <div className=\"mb-3 flex flex-wrap gap-1.5\">\n {action.signals.map((signal) => (\n <Badge key={`${action.id}-${signal}`} variant=\"secondary\" className=\"text-[10px]\">\n {signal}\n </Badge>\n ))}\n </div>\n )}\n\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-muted-foreground\">{action.dueDate ?? \"This week\"}</span>\n\n <div className=\"flex items-center gap-1.5\">\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6\">\n <SkipForward className=\"h-3.5 w-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Skip</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6\">\n <Clock className=\"h-3.5 w-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Snooze</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6\">\n <Users className=\"h-3.5 w-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Delegate</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6\">\n <MessageSquare className=\"h-3.5 w-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Add comment</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </div>\n </div>\n\n <div className=\"mt-3 border-t border-border/50 pt-3\">\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={`h-7 text-xs ${actionFeedback[action.id] === \"useful\" ? \"border-emerald-200 bg-emerald-50 text-emerald-700\" : \"\"}`}\n onClick={() => handleFeedback(action.id, \"useful\")}\n >\n <ThumbsUp className=\"mr-1.5 h-3.5 w-3.5\" />\n Helpful\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={`h-7 text-xs ${actionFeedback[action.id] === \"not_useful\" ? \"border-red-200 bg-red-50 text-red-700\" : \"\"}`}\n onClick={() => handleFeedback(action.id, \"not_useful\")}\n >\n <ThumbsDown className=\"mr-1.5 h-3.5 w-3.5\" />\n Not helpful\n </Button>\n </div>\n\n {commentOpen[action.id] && (\n <div className=\"mt-2 flex gap-2\">\n <input\n type=\"text\"\n value={feedbackComment[action.id] ?? \"\"}\n onChange={(event) =>\n setFeedbackComment((previous) => ({\n ...previous,\n [action.id]: event.target.value,\n }))\n }\n placeholder=\"Optional context for this feedback\"\n className=\"h-8 flex-1 rounded-md border border-border bg-background px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n <Button size=\"sm\" className=\"h-8 text-xs\" onClick={() => submitFeedback(action.id)}>\n Submit\n </Button>\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </section>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface ReportCardFilterOption {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
interface ReportCardProps {
|
|
8
|
+
title: string;
|
|
9
|
+
subtitle?: string;
|
|
10
|
+
/** Filter pill group rendered top-right */
|
|
11
|
+
filterOptions?: ReportCardFilterOption[];
|
|
12
|
+
selectedFilter?: string;
|
|
13
|
+
onFilterChange?: (value: string) => void;
|
|
14
|
+
/** Secondary toggle (e.g. metric selector) */
|
|
15
|
+
toggleOptions?: string[];
|
|
16
|
+
selectedToggle?: string;
|
|
17
|
+
onToggleChange?: (value: string) => void;
|
|
18
|
+
/** Render slot between header and content */
|
|
19
|
+
headerExtra?: React.ReactNode;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
className?: string;
|
|
22
|
+
contentClassName?: string;
|
|
23
|
+
}
|
|
24
|
+
declare function ReportCard({ title, subtitle, filterOptions, selectedFilter, onFilterChange, toggleOptions, selectedToggle, onToggleChange, headerExtra, children, className, contentClassName, }: ReportCardProps): React.JSX.Element;
|
|
25
|
+
|
|
26
|
+
export { ReportCard, type ReportCardProps };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { cn } from "../lib/utils.js";
|
|
6
|
+
function ReportCard({
|
|
7
|
+
title,
|
|
8
|
+
subtitle,
|
|
9
|
+
filterOptions,
|
|
10
|
+
selectedFilter,
|
|
11
|
+
onFilterChange,
|
|
12
|
+
toggleOptions,
|
|
13
|
+
selectedToggle,
|
|
14
|
+
onToggleChange,
|
|
15
|
+
headerExtra,
|
|
16
|
+
children,
|
|
17
|
+
className,
|
|
18
|
+
contentClassName
|
|
19
|
+
}) {
|
|
20
|
+
return /* @__PURE__ */ jsxs(
|
|
21
|
+
"div",
|
|
22
|
+
{
|
|
23
|
+
className: cn(
|
|
24
|
+
"rounded-xl border border-border bg-card shadow-sm",
|
|
25
|
+
className
|
|
26
|
+
),
|
|
27
|
+
children: [
|
|
28
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 border-b border-border/60 px-6 py-5 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
29
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
30
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-bold text-foreground", children: title }),
|
|
31
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: subtitle })
|
|
32
|
+
] }),
|
|
33
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
34
|
+
toggleOptions && toggleOptions.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 rounded-lg bg-muted p-1", children: toggleOptions.map((opt) => /* @__PURE__ */ jsx(
|
|
35
|
+
"button",
|
|
36
|
+
{
|
|
37
|
+
onClick: () => onToggleChange == null ? void 0 : onToggleChange(opt),
|
|
38
|
+
className: cn(
|
|
39
|
+
"rounded-md px-3 py-1 text-xs font-medium transition-all",
|
|
40
|
+
selectedToggle === opt ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
|
|
41
|
+
),
|
|
42
|
+
children: opt
|
|
43
|
+
},
|
|
44
|
+
opt
|
|
45
|
+
)) }),
|
|
46
|
+
filterOptions && filterOptions.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 rounded-lg bg-muted p-1", children: filterOptions.map((opt) => /* @__PURE__ */ jsx(
|
|
47
|
+
"button",
|
|
48
|
+
{
|
|
49
|
+
onClick: () => onFilterChange == null ? void 0 : onFilterChange(opt.value),
|
|
50
|
+
className: cn(
|
|
51
|
+
"h-7 rounded-md border-none bg-transparent px-3 text-xs font-medium shadow-none transition-all hover:bg-white",
|
|
52
|
+
selectedFilter === opt.value && "bg-background text-foreground shadow-sm"
|
|
53
|
+
),
|
|
54
|
+
children: opt.label
|
|
55
|
+
},
|
|
56
|
+
opt.value
|
|
57
|
+
)) })
|
|
58
|
+
] })
|
|
59
|
+
] }),
|
|
60
|
+
headerExtra && /* @__PURE__ */ jsx("div", { className: "border-b border-border/40 px-6 py-3", children: headerExtra }),
|
|
61
|
+
/* @__PURE__ */ jsx("div", { className: cn("p-6", contentClassName), children })
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
ReportCard
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=report-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/report-card.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\n\ninterface ReportCardFilterOption {\n label: string\n value: string\n}\n\nexport interface ReportCardProps {\n title: string\n subtitle?: string\n /** Filter pill group rendered top-right */\n filterOptions?: ReportCardFilterOption[]\n selectedFilter?: string\n onFilterChange?: (value: string) => void\n /** Secondary toggle (e.g. metric selector) */\n toggleOptions?: string[]\n selectedToggle?: string\n onToggleChange?: (value: string) => void\n /** Render slot between header and content */\n headerExtra?: React.ReactNode\n children: React.ReactNode\n className?: string\n contentClassName?: string\n}\n\nexport function ReportCard({\n title,\n subtitle,\n filterOptions,\n selectedFilter,\n onFilterChange,\n toggleOptions,\n selectedToggle,\n onToggleChange,\n headerExtra,\n children,\n className,\n contentClassName,\n}: ReportCardProps) {\n return (\n <div\n className={cn(\n \"rounded-xl border border-border bg-card shadow-sm\",\n className,\n )}\n >\n <div className=\"flex flex-col gap-3 border-b border-border/60 px-6 py-5 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"min-w-0\">\n <h3 className=\"text-sm font-bold text-foreground\">{title}</h3>\n {subtitle && (\n <p className=\"mt-0.5 text-xs text-muted-foreground\">{subtitle}</p>\n )}\n </div>\n\n <div className=\"flex items-center gap-3\">\n {toggleOptions && toggleOptions.length > 1 && (\n <div className=\"flex items-center gap-1 rounded-lg bg-muted p-1\">\n {toggleOptions.map((opt) => (\n <button\n key={opt}\n onClick={() => onToggleChange?.(opt)}\n className={cn(\n \"rounded-md px-3 py-1 text-xs font-medium transition-all\",\n selectedToggle === opt\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n >\n {opt}\n </button>\n ))}\n </div>\n )}\n\n {filterOptions && filterOptions.length > 1 && (\n <div className=\"flex items-center gap-1 rounded-lg bg-muted p-1\">\n {filterOptions.map((opt) => (\n <button\n key={opt.value}\n onClick={() => onFilterChange?.(opt.value)}\n className={cn(\n \"h-7 rounded-md border-none bg-transparent px-3 text-xs font-medium shadow-none transition-all hover:bg-white\",\n selectedFilter === opt.value &&\n \"bg-background text-foreground shadow-sm\",\n )}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {headerExtra && (\n <div className=\"border-b border-border/40 px-6 py-3\">{headerExtra}</div>\n )}\n\n <div className={cn(\"p-6\", contentClassName)}>{children}</div>\n </div>\n )\n}\n"],"mappings":";AAmDQ,SACE,KADF;AA/CR,SAAS,UAAU;AAyBZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,6BAAC,SAAI,WAAU,0GACb;AAAA,+BAAC,SAAI,WAAU,WACb;AAAA,gCAAC,QAAG,WAAU,qCAAqC,iBAAM;AAAA,YACxD,YACC,oBAAC,OAAE,WAAU,wCAAwC,oBAAS;AAAA,aAElE;AAAA,UAEA,qBAAC,SAAI,WAAU,2BACZ;AAAA,6BAAiB,cAAc,SAAS,KACvC,oBAAC,SAAI,WAAU,mDACZ,wBAAc,IAAI,CAAC,QAClB;AAAA,cAAC;AAAA;AAAA,gBAEC,SAAS,MAAM,iDAAiB;AAAA,gBAChC,WAAW;AAAA,kBACT;AAAA,kBACA,mBAAmB,MACf,4CACA;AAAA,gBACN;AAAA,gBAEC;AAAA;AAAA,cATI;AAAA,YAUP,CACD,GACH;AAAA,YAGD,iBAAiB,cAAc,SAAS,KACvC,oBAAC,SAAI,WAAU,mDACZ,wBAAc,IAAI,CAAC,QAClB;AAAA,cAAC;AAAA;AAAA,gBAEC,SAAS,MAAM,iDAAiB,IAAI;AAAA,gBACpC,WAAW;AAAA,kBACT;AAAA,kBACA,mBAAmB,IAAI,SACrB;AAAA,gBACJ;AAAA,gBAEC,cAAI;AAAA;AAAA,cARA,IAAI;AAAA,YASX,CACD,GACH;AAAA,aAEJ;AAAA,WACF;AAAA,QAEC,eACC,oBAAC,SAAI,WAAU,uCAAuC,uBAAY;AAAA,QAGpE,oBAAC,SAAI,WAAW,GAAG,OAAO,gBAAgB,GAAI,UAAS;AAAA;AAAA;AAAA,EACzD;AAEJ;","names":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ScoreFactor } from './score-breakdown.js';
|
|
3
|
+
|
|
4
|
+
interface ScoreAnalysisModalProps {
|
|
5
|
+
open: boolean;
|
|
6
|
+
onOpenChange: (open: boolean) => void;
|
|
7
|
+
title: string;
|
|
8
|
+
description: string;
|
|
9
|
+
score: number;
|
|
10
|
+
denominator?: number;
|
|
11
|
+
whyNow: string;
|
|
12
|
+
evidence: React.ReactNode[];
|
|
13
|
+
factors?: ScoreFactor[];
|
|
14
|
+
onFactorFeedback?: (factorKey: string, type: "up" | "down" | null, detail?: string) => void;
|
|
15
|
+
companyName?: string;
|
|
16
|
+
opportunityUrl?: string;
|
|
17
|
+
onApprove?: () => void;
|
|
18
|
+
onApproveFeedback?: (reasons: string[], detail: string) => void;
|
|
19
|
+
onDismiss?: (reasons: string[], detail: string) => void;
|
|
20
|
+
/** When true, renders as an absolute-positioned inline panel instead of a Radix Sheet portal. Useful when the component is inside a container that should not be escaped. */
|
|
21
|
+
useInlinePanel?: boolean;
|
|
22
|
+
}
|
|
23
|
+
declare function ScoreAnalysisModal({ open, onOpenChange, title, description, score, denominator, whyNow, evidence, factors, onFactorFeedback, companyName, opportunityUrl, onApprove, onApproveFeedback, onDismiss, useInlinePanel, }: ScoreAnalysisModalProps): React.JSX.Element | null;
|
|
24
|
+
declare const ScoreAnalysisPanel: typeof ScoreAnalysisModal;
|
|
25
|
+
|
|
26
|
+
export { ScoreAnalysisModal, type ScoreAnalysisModalProps, ScoreAnalysisPanel };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "./sheet.js";
|
|
6
|
+
import { Badge } from "./badge.js";
|
|
7
|
+
import { ScoreRing } from "./score-ring.js";
|
|
8
|
+
import { ScoreBreakdown } from "./score-breakdown.js";
|
|
9
|
+
import { SignalApproval } from "./signal-feedback-inline.js";
|
|
10
|
+
import { X } from "lucide-react";
|
|
11
|
+
function getScoreLabel(score, denominator) {
|
|
12
|
+
const pct = score / denominator * 100;
|
|
13
|
+
if (pct >= 70) return { text: "HIGH", className: "text-emerald-600" };
|
|
14
|
+
if (pct >= 40) return { text: "MEDIUM", className: "text-amber-600" };
|
|
15
|
+
return { text: "LOW", className: "text-red-600" };
|
|
16
|
+
}
|
|
17
|
+
function ScoreAnalysisModal({
|
|
18
|
+
open,
|
|
19
|
+
onOpenChange,
|
|
20
|
+
title,
|
|
21
|
+
description,
|
|
22
|
+
score,
|
|
23
|
+
denominator = 100,
|
|
24
|
+
whyNow,
|
|
25
|
+
evidence,
|
|
26
|
+
factors,
|
|
27
|
+
onFactorFeedback,
|
|
28
|
+
companyName = "Account",
|
|
29
|
+
opportunityUrl,
|
|
30
|
+
onApprove,
|
|
31
|
+
onApproveFeedback,
|
|
32
|
+
onDismiss,
|
|
33
|
+
useInlinePanel = false
|
|
34
|
+
}) {
|
|
35
|
+
const label = getScoreLabel(score, denominator);
|
|
36
|
+
const panelContent = /* @__PURE__ */ jsxs(
|
|
37
|
+
SignalApproval.Root,
|
|
38
|
+
{
|
|
39
|
+
companyName,
|
|
40
|
+
opportunityUrl,
|
|
41
|
+
onApprove,
|
|
42
|
+
onApproveFeedback,
|
|
43
|
+
onDismiss,
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
|
|
46
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: title }),
|
|
47
|
+
/* @__PURE__ */ jsx(
|
|
48
|
+
"button",
|
|
49
|
+
{
|
|
50
|
+
type: "button",
|
|
51
|
+
onClick: () => onOpenChange(false),
|
|
52
|
+
className: "p-1.5 rounded-md text-muted-foreground hover:bg-secondary transition-colors",
|
|
53
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
] }),
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-6", children: [
|
|
58
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-6", children: description }),
|
|
59
|
+
/* @__PURE__ */ jsx("div", { className: "mb-8", children: /* @__PURE__ */ jsx(SignalApproval.Actions, {}) }),
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
61
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3", children: [
|
|
62
|
+
/* @__PURE__ */ jsx(ScoreRing, { score, denominator, size: 120, strokeWidth: 10 }),
|
|
63
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "outline", children: [
|
|
64
|
+
Math.round(score / denominator * 100),
|
|
65
|
+
"% Score",
|
|
66
|
+
" \u2014 ",
|
|
67
|
+
/* @__PURE__ */ jsx("span", { className: label.className, children: label.text })
|
|
68
|
+
] })
|
|
69
|
+
] }),
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
71
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-2 text-sm", children: "Why Now" }),
|
|
72
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: whyNow })
|
|
73
|
+
] }),
|
|
74
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
75
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-2 text-sm", children: "Supporting Evidence" }),
|
|
76
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-2", children: evidence.map((item, index) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 text-sm", children: [
|
|
77
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-primary rounded-full mt-2 flex-shrink-0" }),
|
|
78
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground leading-relaxed", children: item })
|
|
79
|
+
] }, index)) })
|
|
80
|
+
] }),
|
|
81
|
+
factors && factors.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
82
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-2 text-sm", children: "Score Breakdown" }),
|
|
83
|
+
/* @__PURE__ */ jsx(ScoreBreakdown, { factors, onFactorFeedback })
|
|
84
|
+
] })
|
|
85
|
+
] })
|
|
86
|
+
] })
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
if (useInlinePanel) {
|
|
91
|
+
if (!open) return null;
|
|
92
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "absolute", inset: 0, zIndex: 50, pointerEvents: "auto", overflow: "hidden" }, children: [
|
|
93
|
+
/* @__PURE__ */ jsx(
|
|
94
|
+
"div",
|
|
95
|
+
{
|
|
96
|
+
onClick: () => onOpenChange(false),
|
|
97
|
+
style: { position: "absolute", inset: 0, backgroundColor: "rgba(0,0,0,0.5)", transition: "opacity 200ms" }
|
|
98
|
+
}
|
|
99
|
+
),
|
|
100
|
+
/* @__PURE__ */ jsx(
|
|
101
|
+
"div",
|
|
102
|
+
{
|
|
103
|
+
style: {
|
|
104
|
+
position: "absolute",
|
|
105
|
+
top: 0,
|
|
106
|
+
right: 0,
|
|
107
|
+
bottom: 0,
|
|
108
|
+
width: 500,
|
|
109
|
+
maxWidth: "100%",
|
|
110
|
+
zIndex: 50,
|
|
111
|
+
display: "flex",
|
|
112
|
+
flexDirection: "column",
|
|
113
|
+
overflow: "hidden",
|
|
114
|
+
borderLeft: "1px solid var(--border)",
|
|
115
|
+
backgroundColor: "var(--background, #fff)",
|
|
116
|
+
boxShadow: "-4px 0 24px rgba(0,0,0,0.12)"
|
|
117
|
+
},
|
|
118
|
+
children: panelContent
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
] });
|
|
122
|
+
}
|
|
123
|
+
return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
124
|
+
SheetContent,
|
|
125
|
+
{
|
|
126
|
+
side: "right",
|
|
127
|
+
className: "w-full sm:w-[500px] sm:max-w-[600px] overflow-hidden p-0 bg-background border-l border-border flex flex-col",
|
|
128
|
+
showCloseButton: false,
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ jsx(SheetHeader, { className: "sr-only p-0", children: /* @__PURE__ */ jsx(SheetTitle, { children: title }) }),
|
|
131
|
+
panelContent
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
) });
|
|
135
|
+
}
|
|
136
|
+
const ScoreAnalysisPanel = ScoreAnalysisModal;
|
|
137
|
+
export {
|
|
138
|
+
ScoreAnalysisModal,
|
|
139
|
+
ScoreAnalysisPanel
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=score-analysis-modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/score-analysis-modal.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from \"./sheet\"\nimport { Badge } from \"./badge\"\nimport { ScoreRing } from \"./score-ring\"\nimport { ScoreBreakdown, type ScoreFactor } from \"./score-breakdown\"\nimport { SignalApproval } from \"./signal-feedback-inline\"\nimport { X } from \"lucide-react\"\n\ninterface ScoreAnalysisModalProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n title: string\n description: string\n score: number\n denominator?: number\n whyNow: string\n evidence: React.ReactNode[]\n factors?: ScoreFactor[]\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n companyName?: string\n opportunityUrl?: string\n onApprove?: () => void\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string) => void\n /** When true, renders as an absolute-positioned inline panel instead of a Radix Sheet portal. Useful when the component is inside a container that should not be escaped. */\n useInlinePanel?: boolean\n}\n\nfunction getScoreLabel(score: number, denominator: number) {\n const pct = (score / denominator) * 100\n if (pct >= 70) return { text: \"HIGH\", className: \"text-emerald-600\" }\n if (pct >= 40) return { text: \"MEDIUM\", className: \"text-amber-600\" }\n return { text: \"LOW\", className: \"text-red-600\" }\n}\n\nfunction ScoreAnalysisModal({\n open,\n onOpenChange,\n title,\n description,\n score,\n denominator = 100,\n whyNow,\n evidence,\n factors,\n onFactorFeedback,\n companyName = \"Account\",\n opportunityUrl,\n onApprove,\n onApproveFeedback,\n onDismiss,\n useInlinePanel = false,\n}: ScoreAnalysisModalProps) {\n const label = getScoreLabel(score, denominator)\n\n const panelContent = (\n <SignalApproval.Root\n companyName={companyName}\n opportunityUrl={opportunityUrl}\n onApprove={onApprove}\n onApproveFeedback={onApproveFeedback}\n onDismiss={onDismiss}\n >\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border shrink-0\">\n <h2 className=\"text-lg font-semibold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n onClick={() => onOpenChange(false)}\n className=\"p-1.5 rounded-md text-muted-foreground hover:bg-secondary transition-colors\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-6 py-6\">\n <p className=\"text-sm text-muted-foreground mb-6\">{description}</p>\n\n <div className=\"mb-8\">\n <SignalApproval.Actions />\n </div>\n\n <div className=\"space-y-6\">\n <div className=\"flex flex-col items-center gap-3\">\n <ScoreRing score={score} denominator={denominator} size={120} strokeWidth={10} />\n <Badge variant=\"outline\">\n {Math.round((score / denominator) * 100)}% Score\n {\" \\u2014 \"}\n <span className={label.className}>{label.text}</span>\n </Badge>\n </div>\n\n <div>\n <h3 className=\"font-semibold mb-2 text-sm\">Why Now</h3>\n <p className=\"text-sm text-muted-foreground leading-relaxed\">{whyNow}</p>\n </div>\n\n <div>\n <h3 className=\"font-semibold mb-2 text-sm\">Supporting Evidence</h3>\n <ul className=\"space-y-2\">\n {evidence.map((item, index) => (\n <li key={index} className=\"flex items-start gap-2 text-sm\">\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full mt-2 flex-shrink-0\" />\n <span className=\"text-muted-foreground leading-relaxed\">{item}</span>\n </li>\n ))}\n </ul>\n </div>\n\n {factors && factors.length > 0 && (\n <div>\n <h3 className=\"font-semibold mb-2 text-sm\">Score Breakdown</h3>\n <ScoreBreakdown factors={factors} onFactorFeedback={onFactorFeedback} />\n </div>\n )}\n </div>\n </div>\n </SignalApproval.Root>\n )\n\n if (useInlinePanel) {\n if (!open) return null\n return (\n <div style={{ position: \"absolute\", inset: 0, zIndex: 50, pointerEvents: \"auto\", overflow: \"hidden\" }}>\n <div\n onClick={() => onOpenChange(false)}\n style={{ position: \"absolute\", inset: 0, backgroundColor: \"rgba(0,0,0,0.5)\", transition: \"opacity 200ms\" }}\n />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n bottom: 0,\n width: 500,\n maxWidth: \"100%\",\n zIndex: 50,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n borderLeft: \"1px solid var(--border)\",\n backgroundColor: \"var(--background, #fff)\",\n boxShadow: \"-4px 0 24px rgba(0,0,0,0.12)\",\n }}\n >\n {panelContent}\n </div>\n </div>\n )\n }\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent\n side=\"right\"\n className=\"w-full sm:w-[500px] sm:max-w-[600px] overflow-hidden p-0 bg-background border-l border-border flex flex-col\"\n showCloseButton={false}\n >\n <SheetHeader className=\"sr-only p-0\">\n <SheetTitle>{title}</SheetTitle>\n </SheetHeader>\n {panelContent}\n </SheetContent>\n </Sheet>\n )\n}\n\nconst ScoreAnalysisPanel = ScoreAnalysisModal\n\nexport { ScoreAnalysisModal, ScoreAnalysisPanel }\nexport type { ScoreAnalysisModalProps }\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface ScoreFactor {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
score: number | null;
|
|
7
|
+
risk?: "Low" | "Medium" | "High";
|
|
8
|
+
why: string;
|
|
9
|
+
}
|
|
10
|
+
interface ScoreBreakdownProps {
|
|
11
|
+
factors: ScoreFactor[];
|
|
12
|
+
onFactorFeedback?: (factorKey: string, type: "up" | "down" | null, detail?: string) => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
declare function ScoreBreakdown({ factors, onFactorFeedback, className }: ScoreBreakdownProps): React.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { ScoreBreakdown, type ScoreBreakdownProps, type ScoreFactor };
|