@wealthx/shadcn 1.5.1 → 1.5.2
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/.turbo/turbo-build.log +118 -118
- package/CHANGELOG.md +6 -0
- package/dist/chunk-G2EWIP2N.mjs +960 -0
- package/dist/{chunk-MHHA7QGO.mjs → chunk-ODO6BUOF.mjs} +1 -1
- package/dist/chunk-PX4M67XQ.mjs +301 -0
- package/dist/{chunk-FYUSF5KO.mjs → chunk-QRVEI6J3.mjs} +1 -1
- package/dist/{chunk-42NEC57Y.mjs → chunk-RAKBWNQH.mjs} +272 -3
- package/dist/components/ui/{contact-alert-dialog.js → contact-alert-dialog/index.js} +1029 -593
- package/dist/components/ui/contact-alert-dialog/index.mjs +31 -0
- package/dist/components/ui/file-preview-dialog.js +407 -100
- package/dist/components/ui/file-preview-dialog.mjs +3 -1
- package/dist/components/ui/kanban-column.js +408 -113
- package/dist/components/ui/kanban-column.mjs +3 -2
- package/dist/components/ui/opportunity-card.js +383 -88
- package/dist/components/ui/opportunity-card.mjs +2 -1
- package/dist/components/ui/pipeline-board.js +424 -129
- package/dist/components/ui/pipeline-board.mjs +4 -3
- package/dist/index.js +3081 -2282
- package/dist/index.mjs +39 -35
- package/dist/styles.css +1 -1
- package/package.json +5 -4
- package/src/components/index.tsx +3 -2
- package/src/components/ui/contact-alert-dialog/builder-ui.tsx +556 -0
- package/src/components/ui/contact-alert-dialog/config.ts +262 -0
- package/src/components/ui/contact-alert-dialog/contact-alert-dialog.tsx +214 -0
- package/src/components/ui/contact-alert-dialog/index.tsx +15 -0
- package/src/components/ui/contact-alert-dialog/types.ts +61 -0
- package/src/components/ui/contact-alert-dialog/utils.ts +93 -0
- package/src/components/ui/file-preview-dialog.tsx +299 -99
- package/src/components/ui/opportunity-card.tsx +328 -1
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +1 -1
- package/dist/chunk-5WMFKQZ6.mjs +0 -180
- package/dist/chunk-Y24TXIFJ.mjs +0 -518
- package/dist/components/ui/contact-alert-dialog.mjs +0 -27
- package/src/components/ui/contact-alert-dialog.tsx +0 -710
|
@@ -532,6 +532,7 @@ function DropdownMenuSeparator(_a) {
|
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
// src/components/ui/opportunity-card.tsx
|
|
535
|
+
var import_react5 = require("react");
|
|
535
536
|
var import_lucide_react6 = require("lucide-react");
|
|
536
537
|
|
|
537
538
|
// src/lib/format-date.ts
|
|
@@ -820,16 +821,48 @@ function TaskCheckItem({
|
|
|
820
821
|
);
|
|
821
822
|
}
|
|
822
823
|
|
|
824
|
+
// src/components/ui/progress.tsx
|
|
825
|
+
var import_progress = require("@base-ui/react/progress");
|
|
826
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
827
|
+
function Progress(_a) {
|
|
828
|
+
var _b = _a, {
|
|
829
|
+
className,
|
|
830
|
+
value
|
|
831
|
+
} = _b, props = __objRest(_b, [
|
|
832
|
+
"className",
|
|
833
|
+
"value"
|
|
834
|
+
]);
|
|
835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
836
|
+
import_progress.Progress.Root,
|
|
837
|
+
__spreadProps(__spreadValues({
|
|
838
|
+
className: cn(
|
|
839
|
+
"relative h-2 w-full overflow-hidden bg-muted",
|
|
840
|
+
className
|
|
841
|
+
),
|
|
842
|
+
"data-slot": "progress",
|
|
843
|
+
value
|
|
844
|
+
}, props), {
|
|
845
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_progress.Progress.Track, { className: "h-full", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
846
|
+
import_progress.Progress.Indicator,
|
|
847
|
+
{
|
|
848
|
+
className: "h-full bg-primary transition-all",
|
|
849
|
+
"data-slot": "progress-indicator"
|
|
850
|
+
}
|
|
851
|
+
) })
|
|
852
|
+
})
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
|
|
823
856
|
// src/components/ui/tooltip.tsx
|
|
824
857
|
var import_tooltip = require("@base-ui/react/tooltip");
|
|
825
|
-
var
|
|
858
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
826
859
|
function TooltipProvider(_a) {
|
|
827
860
|
var _b = _a, {
|
|
828
861
|
delay = 0
|
|
829
862
|
} = _b, props = __objRest(_b, [
|
|
830
863
|
"delay"
|
|
831
864
|
]);
|
|
832
|
-
return /* @__PURE__ */ (0,
|
|
865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
833
866
|
import_tooltip.Tooltip.Provider,
|
|
834
867
|
__spreadValues({
|
|
835
868
|
"data-slot": "tooltip-provider",
|
|
@@ -839,11 +872,11 @@ function TooltipProvider(_a) {
|
|
|
839
872
|
}
|
|
840
873
|
function Tooltip(_a) {
|
|
841
874
|
var props = __objRest(_a, []);
|
|
842
|
-
return /* @__PURE__ */ (0,
|
|
875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
|
|
843
876
|
}
|
|
844
877
|
function TooltipTrigger(_a) {
|
|
845
878
|
var props = __objRest(_a, []);
|
|
846
|
-
return /* @__PURE__ */ (0,
|
|
879
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
|
|
847
880
|
}
|
|
848
881
|
function TooltipContent(_a) {
|
|
849
882
|
var _b = _a, {
|
|
@@ -860,7 +893,7 @@ function TooltipContent(_a) {
|
|
|
860
893
|
"style"
|
|
861
894
|
]);
|
|
862
895
|
const themeVars = useThemeVars();
|
|
863
|
-
return /* @__PURE__ */ (0,
|
|
896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
864
897
|
import_tooltip.Tooltip.Popup,
|
|
865
898
|
__spreadProps(__spreadValues({
|
|
866
899
|
className: cn(
|
|
@@ -872,14 +905,14 @@ function TooltipContent(_a) {
|
|
|
872
905
|
}, props), {
|
|
873
906
|
children: [
|
|
874
907
|
children,
|
|
875
|
-
/* @__PURE__ */ (0,
|
|
908
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_tooltip.Tooltip.Arrow, { className: "z-50 size-2.5 rotate-45 bg-brand-secondary data-[side=bottom]:-top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-1" })
|
|
876
909
|
]
|
|
877
910
|
})
|
|
878
911
|
) }) });
|
|
879
912
|
}
|
|
880
913
|
|
|
881
914
|
// src/components/ui/opportunity-card.tsx
|
|
882
|
-
var
|
|
915
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
883
916
|
var PRIORITY_COLORS = {
|
|
884
917
|
HIGH: "var(--color-destructive)",
|
|
885
918
|
MEDIUM: "var(--color-warning)",
|
|
@@ -902,7 +935,233 @@ function resolvePriority(days, warningDays, priorityDays, priority) {
|
|
|
902
935
|
function formatLoanType(type) {
|
|
903
936
|
return type.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
904
937
|
}
|
|
938
|
+
function TaskViewCard({
|
|
939
|
+
customerName,
|
|
940
|
+
loanType,
|
|
941
|
+
loanPurposeLabel,
|
|
942
|
+
amount,
|
|
943
|
+
priority,
|
|
944
|
+
daysSinceColumnChanged,
|
|
945
|
+
warningDays,
|
|
946
|
+
priorityDays,
|
|
947
|
+
tasks = [],
|
|
948
|
+
nextTask,
|
|
949
|
+
onCardClick,
|
|
950
|
+
onViewDetails,
|
|
951
|
+
onTaskToggle,
|
|
952
|
+
onMarkAsDone,
|
|
953
|
+
onMoveToNextStage,
|
|
954
|
+
onChangePriority,
|
|
955
|
+
onDelete,
|
|
956
|
+
onPutOnHold,
|
|
957
|
+
isSubmitting = false,
|
|
958
|
+
draggable = false,
|
|
959
|
+
onDragStart,
|
|
960
|
+
className
|
|
961
|
+
}) {
|
|
962
|
+
var _a;
|
|
963
|
+
const resolvedPriority = resolvePriority(
|
|
964
|
+
daysSinceColumnChanged,
|
|
965
|
+
warningDays,
|
|
966
|
+
priorityDays,
|
|
967
|
+
priority
|
|
968
|
+
);
|
|
969
|
+
const priorityColor = PRIORITY_COLORS[resolvedPriority];
|
|
970
|
+
const completedCount = tasks.filter((t) => t.completed).length;
|
|
971
|
+
const totalCount = tasks.length;
|
|
972
|
+
const hasTasks = totalCount > 0;
|
|
973
|
+
const allDone = hasTasks && completedCount === totalCount;
|
|
974
|
+
const nextPendingTask = tasks.find((t) => !t.completed);
|
|
975
|
+
const agentName = (_a = nextPendingTask == null ? void 0 : nextPendingTask.aiAgentName) != null ? _a : null;
|
|
976
|
+
const [subtasksExpanded, setSubtasksExpanded] = (0, import_react5.useState)(false);
|
|
977
|
+
const hasMenu = onViewDetails || onChangePriority || onPutOnHold || onDelete;
|
|
978
|
+
const stopProp = (e) => {
|
|
979
|
+
e.stopPropagation();
|
|
980
|
+
};
|
|
981
|
+
const purposeLabel = loanPurposeLabel != null ? loanPurposeLabel : loanType ? formatLoanType(loanType) : null;
|
|
982
|
+
const dealRef = [
|
|
983
|
+
customerName,
|
|
984
|
+
purposeLabel,
|
|
985
|
+
amount > 0 ? formatCurrency(amount) : null
|
|
986
|
+
].filter(Boolean).join(" \xB7 ");
|
|
987
|
+
let taskHeader;
|
|
988
|
+
if (allDone) {
|
|
989
|
+
taskHeader = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
990
|
+
"p",
|
|
991
|
+
{
|
|
992
|
+
className: "flex items-center gap-1.5 text-sm font-semibold",
|
|
993
|
+
style: { color: "var(--color-success-text)" },
|
|
994
|
+
children: [
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Check, { className: "size-3.5 shrink-0" }),
|
|
996
|
+
"All tasks complete"
|
|
997
|
+
]
|
|
998
|
+
}
|
|
999
|
+
);
|
|
1000
|
+
} else if (nextTask) {
|
|
1001
|
+
taskHeader = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1002
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
1003
|
+
agentName && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1004
|
+
import_lucide_react6.Bot,
|
|
1005
|
+
{
|
|
1006
|
+
className: "size-3.5 shrink-0 text-primary",
|
|
1007
|
+
"aria-hidden": "true"
|
|
1008
|
+
}
|
|
1009
|
+
),
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "truncate text-sm font-semibold leading-snug", children: nextTask })
|
|
1011
|
+
] }),
|
|
1012
|
+
agentName && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: agentName })
|
|
1013
|
+
] });
|
|
1014
|
+
} else {
|
|
1015
|
+
taskHeader = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-muted-foreground", children: "No tasks defined for this stage" });
|
|
1016
|
+
}
|
|
1017
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1018
|
+
"div",
|
|
1019
|
+
{
|
|
1020
|
+
className: cn(
|
|
1021
|
+
"flex flex-col gap-2.5 border border-border bg-background p-3 text-foreground shadow-sm",
|
|
1022
|
+
onCardClick && "cursor-pointer",
|
|
1023
|
+
draggable && "cursor-grab active:cursor-grabbing",
|
|
1024
|
+
isSubmitting && "opacity-60",
|
|
1025
|
+
className
|
|
1026
|
+
),
|
|
1027
|
+
"data-slot": "opportunity-card",
|
|
1028
|
+
draggable,
|
|
1029
|
+
onDragStart,
|
|
1030
|
+
onClick: onCardClick,
|
|
1031
|
+
children: [
|
|
1032
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-start gap-2", children: [
|
|
1033
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "min-w-0 flex-1", children: taskHeader }),
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1035
|
+
"span",
|
|
1036
|
+
{
|
|
1037
|
+
role: "img",
|
|
1038
|
+
className: "mt-0.5 inline-block size-2.5 shrink-0 rounded-full",
|
|
1039
|
+
style: { backgroundColor: priorityColor },
|
|
1040
|
+
"aria-label": `Priority: ${resolvedPriority}`
|
|
1041
|
+
}
|
|
1042
|
+
)
|
|
1043
|
+
] }),
|
|
1044
|
+
hasTasks && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1045
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "shrink-0 tabular-nums text-xs text-muted-foreground", children: [
|
|
1046
|
+
completedCount,
|
|
1047
|
+
"/",
|
|
1048
|
+
totalCount
|
|
1049
|
+
] }),
|
|
1050
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1051
|
+
Progress,
|
|
1052
|
+
{
|
|
1053
|
+
value: completedCount / totalCount * 100,
|
|
1054
|
+
className: cn(
|
|
1055
|
+
"h-1.5 flex-1",
|
|
1056
|
+
allDone && "[&_[data-slot=progress-indicator]]:bg-success"
|
|
1057
|
+
)
|
|
1058
|
+
}
|
|
1059
|
+
)
|
|
1060
|
+
] }),
|
|
1061
|
+
hasTasks && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1062
|
+
"div",
|
|
1063
|
+
{
|
|
1064
|
+
className: "space-y-1 border-t border-border pt-2",
|
|
1065
|
+
onClick: stopProp,
|
|
1066
|
+
role: "presentation",
|
|
1067
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
1068
|
+
children: [
|
|
1069
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1070
|
+
"button",
|
|
1071
|
+
{
|
|
1072
|
+
type: "button",
|
|
1073
|
+
onClick: () => setSubtasksExpanded((v) => !v),
|
|
1074
|
+
className: "flex w-full items-center justify-between text-xs text-muted-foreground hover:text-foreground",
|
|
1075
|
+
children: [
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1", children: [
|
|
1077
|
+
subtasksExpanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.ChevronDown, { className: "size-3" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.ChevronRight, { className: "size-3" }),
|
|
1078
|
+
"Subtasks"
|
|
1079
|
+
] }),
|
|
1080
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { children: [
|
|
1081
|
+
completedCount,
|
|
1082
|
+
" / ",
|
|
1083
|
+
totalCount
|
|
1084
|
+
] })
|
|
1085
|
+
]
|
|
1086
|
+
}
|
|
1087
|
+
),
|
|
1088
|
+
subtasksExpanded && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "space-y-1.5 pt-1", children: tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1089
|
+
TaskCheckItem,
|
|
1090
|
+
{
|
|
1091
|
+
title: task.title,
|
|
1092
|
+
completed: task.completed,
|
|
1093
|
+
aiAgentName: task.aiAgentName,
|
|
1094
|
+
onToggle: () => onTaskToggle == null ? void 0 : onTaskToggle(task.id),
|
|
1095
|
+
size: "xs"
|
|
1096
|
+
},
|
|
1097
|
+
task.id
|
|
1098
|
+
)) })
|
|
1099
|
+
]
|
|
1100
|
+
}
|
|
1101
|
+
),
|
|
1102
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: dealRef }),
|
|
1103
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1.5", onClick: stopProp, children: [
|
|
1104
|
+
daysSinceColumnChanged !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Badge, { variant: "secondary", className: "px-1.5 text-[10px] font-normal", children: [
|
|
1105
|
+
daysSinceColumnChanged,
|
|
1106
|
+
"d"
|
|
1107
|
+
] }),
|
|
1108
|
+
hasMenu && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ml-auto", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(DropdownMenu, { children: [
|
|
1109
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1110
|
+
DropdownMenuTrigger,
|
|
1111
|
+
{
|
|
1112
|
+
className: cn(
|
|
1113
|
+
buttonVariants({ variant: "ghost", size: "icon" }),
|
|
1114
|
+
"size-7 shrink-0"
|
|
1115
|
+
),
|
|
1116
|
+
"aria-label": "Opportunity actions",
|
|
1117
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.MoreVertical, { className: "size-4" })
|
|
1118
|
+
}
|
|
1119
|
+
),
|
|
1120
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
1121
|
+
onViewDetails && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onViewDetails, children: "View details" }),
|
|
1122
|
+
onChangePriority && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onChangePriority, children: "Change priority" }),
|
|
1123
|
+
onPutOnHold && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onPutOnHold, children: "Put on hold" }),
|
|
1124
|
+
onDelete && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuSeparator, {}),
|
|
1126
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onDelete, variant: "destructive", children: "Delete" })
|
|
1127
|
+
] })
|
|
1128
|
+
] })
|
|
1129
|
+
] }) })
|
|
1130
|
+
] }),
|
|
1131
|
+
allDone && onMoveToNextStage && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { onClick: stopProp, children: [
|
|
1132
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Separator, {}),
|
|
1133
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1134
|
+
Button,
|
|
1135
|
+
{
|
|
1136
|
+
variant: "outline",
|
|
1137
|
+
size: "sm",
|
|
1138
|
+
className: "w-full text-caption",
|
|
1139
|
+
onClick: onMoveToNextStage,
|
|
1140
|
+
disabled: isSubmitting,
|
|
1141
|
+
children: "Move to next stage"
|
|
1142
|
+
}
|
|
1143
|
+
) })
|
|
1144
|
+
] }),
|
|
1145
|
+
!allDone && nextTask && onMarkAsDone && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { onClick: stopProp, children: [
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Separator, {}),
|
|
1147
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1148
|
+
Button,
|
|
1149
|
+
{
|
|
1150
|
+
variant: "default",
|
|
1151
|
+
size: "sm",
|
|
1152
|
+
className: "w-full text-caption",
|
|
1153
|
+
onClick: onMarkAsDone,
|
|
1154
|
+
disabled: isSubmitting,
|
|
1155
|
+
children: "Mark as done"
|
|
1156
|
+
}
|
|
1157
|
+
) })
|
|
1158
|
+
] })
|
|
1159
|
+
]
|
|
1160
|
+
}
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
905
1163
|
function OpportunityCard({
|
|
1164
|
+
id,
|
|
906
1165
|
customerName,
|
|
907
1166
|
customerPhone,
|
|
908
1167
|
customerEmail,
|
|
@@ -931,8 +1190,42 @@ function OpportunityCard({
|
|
|
931
1190
|
isSubmitting = false,
|
|
932
1191
|
draggable = false,
|
|
933
1192
|
onDragStart,
|
|
934
|
-
className
|
|
1193
|
+
className,
|
|
1194
|
+
viewMode = "deal"
|
|
935
1195
|
}) {
|
|
1196
|
+
if (viewMode === "task") {
|
|
1197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1198
|
+
TaskViewCard,
|
|
1199
|
+
{
|
|
1200
|
+
customerName,
|
|
1201
|
+
customerPhone,
|
|
1202
|
+
customerEmail,
|
|
1203
|
+
additionalContacts,
|
|
1204
|
+
loanType,
|
|
1205
|
+
loanPurposeLabel,
|
|
1206
|
+
amount,
|
|
1207
|
+
date,
|
|
1208
|
+
priority,
|
|
1209
|
+
daysSinceColumnChanged,
|
|
1210
|
+
warningDays,
|
|
1211
|
+
priorityDays,
|
|
1212
|
+
tasks,
|
|
1213
|
+
nextTask,
|
|
1214
|
+
onCardClick,
|
|
1215
|
+
onViewDetails,
|
|
1216
|
+
onTaskToggle,
|
|
1217
|
+
onMarkAsDone,
|
|
1218
|
+
onMoveToNextStage,
|
|
1219
|
+
onChangePriority,
|
|
1220
|
+
onDelete,
|
|
1221
|
+
onPutOnHold,
|
|
1222
|
+
isSubmitting,
|
|
1223
|
+
draggable,
|
|
1224
|
+
onDragStart,
|
|
1225
|
+
className
|
|
1226
|
+
}
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
936
1229
|
const resolvedPriority = resolvePriority(
|
|
937
1230
|
daysSinceColumnChanged,
|
|
938
1231
|
warningDays,
|
|
@@ -945,8 +1238,10 @@ function OpportunityCard({
|
|
|
945
1238
|
const hasTasks = tasks.length > 0;
|
|
946
1239
|
const hasActions = onMarkAsDone || onMoveToNextStage;
|
|
947
1240
|
const hasMenu = onViewDetails || onChangePriority || onPutOnHold || onDelete;
|
|
948
|
-
const stopProp = (e) =>
|
|
949
|
-
|
|
1241
|
+
const stopProp = (e) => {
|
|
1242
|
+
e.stopPropagation();
|
|
1243
|
+
};
|
|
1244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
950
1245
|
"div",
|
|
951
1246
|
{
|
|
952
1247
|
className: cn(
|
|
@@ -961,19 +1256,19 @@ function OpportunityCard({
|
|
|
961
1256
|
onDragStart,
|
|
962
1257
|
onClick: onCardClick,
|
|
963
1258
|
children: [
|
|
964
|
-
onHoldTo && /* @__PURE__ */ (0,
|
|
1259
|
+
onHoldTo && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
965
1260
|
"div",
|
|
966
1261
|
{
|
|
967
1262
|
className: "flex items-center gap-1.5 rounded border border-warning/30 bg-warning/10 px-2 py-1 text-xs font-medium",
|
|
968
1263
|
style: { color: "var(--color-warning-text)" },
|
|
969
1264
|
children: [
|
|
970
|
-
/* @__PURE__ */ (0,
|
|
1265
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Clock, { className: "size-3 shrink-0" }),
|
|
971
1266
|
"On hold until ",
|
|
972
1267
|
formatDateDayMonth(onHoldTo)
|
|
973
1268
|
]
|
|
974
1269
|
}
|
|
975
1270
|
),
|
|
976
|
-
isModifyCompletedLoan && /* @__PURE__ */ (0,
|
|
1271
|
+
isModifyCompletedLoan && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
977
1272
|
"div",
|
|
978
1273
|
{
|
|
979
1274
|
className: "flex items-center gap-1.5 rounded border border-info/30 bg-info/10 px-2 py-1 text-xs font-medium",
|
|
@@ -981,14 +1276,14 @@ function OpportunityCard({
|
|
|
981
1276
|
children: "Modify completed loan"
|
|
982
1277
|
}
|
|
983
1278
|
),
|
|
984
|
-
/* @__PURE__ */ (0,
|
|
985
|
-
/* @__PURE__ */ (0,
|
|
986
|
-
(loanPurposeLabel || loanType) && /* @__PURE__ */ (0,
|
|
987
|
-
/* @__PURE__ */ (0,
|
|
1279
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
1280
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
1281
|
+
(loanPurposeLabel || loanType) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Badge, { variant: "outline", className: "self-start", children: loanPurposeLabel != null ? loanPurposeLabel : formatLoanType(loanType) }),
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-base font-bold tabular-nums text-foreground", children: formatCurrency(amount) })
|
|
988
1283
|
] }),
|
|
989
|
-
/* @__PURE__ */ (0,
|
|
990
|
-
onLaunchAssistant && /* @__PURE__ */ (0,
|
|
991
|
-
/* @__PURE__ */ (0,
|
|
1284
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1 -mr-1 -mt-1", onClick: stopProp, children: [
|
|
1285
|
+
onLaunchAssistant && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipProvider, { delay: 0, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
|
|
1286
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
992
1287
|
Button,
|
|
993
1288
|
{
|
|
994
1289
|
type: "button",
|
|
@@ -997,13 +1292,13 @@ function OpportunityCard({
|
|
|
997
1292
|
className: "size-7 shrink-0",
|
|
998
1293
|
onClick: onLaunchAssistant,
|
|
999
1294
|
"aria-label": "Launch AI",
|
|
1000
|
-
children: /* @__PURE__ */ (0,
|
|
1295
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Bot, { className: "size-4" })
|
|
1001
1296
|
}
|
|
1002
1297
|
) }),
|
|
1003
|
-
/* @__PURE__ */ (0,
|
|
1298
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipContent, { children: "Launch AI" })
|
|
1004
1299
|
] }) }),
|
|
1005
|
-
hasMenu && /* @__PURE__ */ (0,
|
|
1006
|
-
/* @__PURE__ */ (0,
|
|
1300
|
+
hasMenu && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(DropdownMenu, { children: [
|
|
1301
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1007
1302
|
DropdownMenuTrigger,
|
|
1008
1303
|
{
|
|
1009
1304
|
className: cn(
|
|
@@ -1011,51 +1306,51 @@ function OpportunityCard({
|
|
|
1011
1306
|
"size-7 shrink-0"
|
|
1012
1307
|
),
|
|
1013
1308
|
"aria-label": "Opportunity actions",
|
|
1014
|
-
children: /* @__PURE__ */ (0,
|
|
1309
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.MoreVertical, { className: "size-4" })
|
|
1015
1310
|
}
|
|
1016
1311
|
),
|
|
1017
|
-
/* @__PURE__ */ (0,
|
|
1018
|
-
onViewDetails && /* @__PURE__ */ (0,
|
|
1019
|
-
onChangePriority && /* @__PURE__ */ (0,
|
|
1020
|
-
onPutOnHold && /* @__PURE__ */ (0,
|
|
1021
|
-
onDelete && /* @__PURE__ */ (0,
|
|
1022
|
-
/* @__PURE__ */ (0,
|
|
1023
|
-
/* @__PURE__ */ (0,
|
|
1312
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
1313
|
+
onViewDetails && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onViewDetails, children: "View details" }),
|
|
1314
|
+
onChangePriority && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onChangePriority, children: "Change priority" }),
|
|
1315
|
+
onPutOnHold && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onPutOnHold, children: "Put on hold" }),
|
|
1316
|
+
onDelete && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1317
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuSeparator, {}),
|
|
1318
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuItem, { onClick: onDelete, variant: "destructive", children: "Delete" })
|
|
1024
1319
|
] })
|
|
1025
1320
|
] })
|
|
1026
1321
|
] })
|
|
1027
1322
|
] })
|
|
1028
1323
|
] }),
|
|
1029
|
-
/* @__PURE__ */ (0,
|
|
1030
|
-
/* @__PURE__ */ (0,
|
|
1031
|
-
/* @__PURE__ */ (0,
|
|
1032
|
-
/* @__PURE__ */ (0,
|
|
1033
|
-
additionalContacts && additionalContacts > 0 ? /* @__PURE__ */ (0,
|
|
1034
|
-
/* @__PURE__ */ (0,
|
|
1324
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Separator, {}),
|
|
1325
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1326
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1327
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate text-sm font-semibold text-foreground", children: customerName }),
|
|
1328
|
+
additionalContacts && additionalContacts > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Badge, { variant: "secondary", className: "shrink-0 gap-1", children: [
|
|
1329
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Users, { className: "size-3", "aria-hidden": "true" }),
|
|
1035
1330
|
"Joint"
|
|
1036
|
-
] }) : /* @__PURE__ */ (0,
|
|
1037
|
-
/* @__PURE__ */ (0,
|
|
1331
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Badge, { variant: "secondary", className: "shrink-0 gap-1", children: [
|
|
1332
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.User, { className: "size-3", "aria-hidden": "true" }),
|
|
1038
1333
|
"Individual"
|
|
1039
1334
|
] })
|
|
1040
1335
|
] }),
|
|
1041
|
-
customerPhone && /* @__PURE__ */ (0,
|
|
1042
|
-
/* @__PURE__ */ (0,
|
|
1336
|
+
customerPhone && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1337
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Phone, { className: "size-3 shrink-0", "aria-hidden": "true" }),
|
|
1043
1338
|
customerPhone
|
|
1044
1339
|
] }),
|
|
1045
|
-
customerEmail && /* @__PURE__ */ (0,
|
|
1046
|
-
/* @__PURE__ */ (0,
|
|
1047
|
-
/* @__PURE__ */ (0,
|
|
1340
|
+
customerEmail && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1341
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Mail, { className: "size-3 shrink-0", "aria-hidden": "true" }),
|
|
1342
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate", children: customerEmail })
|
|
1048
1343
|
] })
|
|
1049
1344
|
] }),
|
|
1050
|
-
/* @__PURE__ */ (0,
|
|
1051
|
-
/* @__PURE__ */ (0,
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Separator, {}),
|
|
1346
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1347
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Calendar, { className: "size-3 shrink-0", "aria-hidden": "true" }),
|
|
1054
1349
|
formatDateShort(date)
|
|
1055
1350
|
] }),
|
|
1056
|
-
/* @__PURE__ */ (0,
|
|
1057
|
-
daysSinceColumnChanged !== void 0 && /* @__PURE__ */ (0,
|
|
1058
|
-
/* @__PURE__ */ (0,
|
|
1351
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
1352
|
+
daysSinceColumnChanged !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1353
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1059
1354
|
import_lucide_react6.Clock,
|
|
1060
1355
|
{
|
|
1061
1356
|
className: "size-3 shrink-0",
|
|
@@ -1063,7 +1358,7 @@ function OpportunityCard({
|
|
|
1063
1358
|
"aria-hidden": "true"
|
|
1064
1359
|
}
|
|
1065
1360
|
),
|
|
1066
|
-
/* @__PURE__ */ (0,
|
|
1361
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1067
1362
|
"span",
|
|
1068
1363
|
{
|
|
1069
1364
|
className: "text-xs font-medium tabular-nums",
|
|
@@ -1075,7 +1370,7 @@ function OpportunityCard({
|
|
|
1075
1370
|
}
|
|
1076
1371
|
)
|
|
1077
1372
|
] }),
|
|
1078
|
-
/* @__PURE__ */ (0,
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1079
1374
|
"span",
|
|
1080
1375
|
{
|
|
1081
1376
|
role: "img",
|
|
@@ -1087,8 +1382,8 @@ function OpportunityCard({
|
|
|
1087
1382
|
] })
|
|
1088
1383
|
] }),
|
|
1089
1384
|
hasTasks && // stopPropagation: accordion expand/collapse + task checkboxes must not bubble to onCardClick
|
|
1090
|
-
/* @__PURE__ */ (0,
|
|
1091
|
-
/* @__PURE__ */ (0,
|
|
1385
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { onClick: stopProp, children: [
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1092
1387
|
"div",
|
|
1093
1388
|
{
|
|
1094
1389
|
className: "flex gap-0.5",
|
|
@@ -1097,7 +1392,7 @@ function OpportunityCard({
|
|
|
1097
1392
|
"aria-valuemin": 0,
|
|
1098
1393
|
"aria-valuemax": tasks.length,
|
|
1099
1394
|
"aria-label": `${completedCount} of ${tasks.length} tasks complete`,
|
|
1100
|
-
children: tasks.map((t, i) => /* @__PURE__ */ (0,
|
|
1395
|
+
children: tasks.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1101
1396
|
"div",
|
|
1102
1397
|
{
|
|
1103
1398
|
className: cn(
|
|
@@ -1109,15 +1404,15 @@ function OpportunityCard({
|
|
|
1109
1404
|
))
|
|
1110
1405
|
}
|
|
1111
1406
|
),
|
|
1112
|
-
/* @__PURE__ */ (0,
|
|
1113
|
-
/* @__PURE__ */ (0,
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Accordion, { type: "single", collapsible: true, className: "-mx-4", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(AccordionItem, { value: "tasks", className: "border-0", children: [
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(AccordionTrigger, { className: "px-4 py-1.5 text-xs font-normal text-muted-foreground hover:no-underline hover:text-foreground [&>svg]:size-3.5", children: [
|
|
1114
1409
|
"Tasks (",
|
|
1115
1410
|
completedCount,
|
|
1116
1411
|
"/",
|
|
1117
1412
|
tasks.length,
|
|
1118
1413
|
")"
|
|
1119
1414
|
] }),
|
|
1120
|
-
/* @__PURE__ */ (0,
|
|
1415
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AccordionContent, { className: "px-4", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-col", children: tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1121
1416
|
TaskCheckItem,
|
|
1122
1417
|
{
|
|
1123
1418
|
title: task.title,
|
|
@@ -1129,23 +1424,23 @@ function OpportunityCard({
|
|
|
1129
1424
|
task.id
|
|
1130
1425
|
)) }) })
|
|
1131
1426
|
] }) }),
|
|
1132
|
-
nextTask && /* @__PURE__ */ (0,
|
|
1133
|
-
/* @__PURE__ */ (0,
|
|
1427
|
+
nextTask && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-start gap-1.5 border border-primary/30 bg-primary/5 px-2 py-1.5 text-xs", children: [
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1134
1429
|
import_lucide_react6.ArrowRight,
|
|
1135
1430
|
{
|
|
1136
1431
|
className: "mt-0.5 size-3 shrink-0 text-primary",
|
|
1137
1432
|
"aria-hidden": "true"
|
|
1138
1433
|
}
|
|
1139
1434
|
),
|
|
1140
|
-
/* @__PURE__ */ (0,
|
|
1141
|
-
/* @__PURE__ */ (0,
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-medium", children: "Next:" }),
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-muted-foreground", children: nextTask })
|
|
1142
1437
|
] })
|
|
1143
1438
|
] }),
|
|
1144
1439
|
hasActions && // stopPropagation: button clicks must not bubble to onCardClick
|
|
1145
|
-
/* @__PURE__ */ (0,
|
|
1146
|
-
/* @__PURE__ */ (0,
|
|
1147
|
-
(onMoveToNextStage || onMarkAsDone) && /* @__PURE__ */ (0,
|
|
1148
|
-
onMoveToNextStage && /* @__PURE__ */ (0,
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { onClick: stopProp, children: [
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Separator, {}),
|
|
1442
|
+
(onMoveToNextStage || onMarkAsDone) && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-2 pt-2", children: [
|
|
1443
|
+
onMoveToNextStage && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1149
1444
|
Button,
|
|
1150
1445
|
{
|
|
1151
1446
|
variant: "outline",
|
|
@@ -1156,7 +1451,7 @@ function OpportunityCard({
|
|
|
1156
1451
|
children: "Move to next stage"
|
|
1157
1452
|
}
|
|
1158
1453
|
),
|
|
1159
|
-
onMarkAsDone && /* @__PURE__ */ (0,
|
|
1454
|
+
onMarkAsDone && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1160
1455
|
Button,
|
|
1161
1456
|
{
|
|
1162
1457
|
variant: "default",
|
|
@@ -1183,7 +1478,7 @@ function LeadCard({
|
|
|
1183
1478
|
isSubmitting = false,
|
|
1184
1479
|
className
|
|
1185
1480
|
}) {
|
|
1186
|
-
return /* @__PURE__ */ (0,
|
|
1481
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1187
1482
|
"div",
|
|
1188
1483
|
{
|
|
1189
1484
|
className: cn(
|
|
@@ -1193,20 +1488,20 @@ function LeadCard({
|
|
|
1193
1488
|
),
|
|
1194
1489
|
"data-slot": "lead-card",
|
|
1195
1490
|
children: [
|
|
1196
|
-
/* @__PURE__ */ (0,
|
|
1197
|
-
/* @__PURE__ */ (0,
|
|
1198
|
-
/* @__PURE__ */ (0,
|
|
1199
|
-
customerPhone && /* @__PURE__ */ (0,
|
|
1200
|
-
/* @__PURE__ */ (0,
|
|
1491
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
1493
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm font-semibold text-foreground", children: customerName }),
|
|
1494
|
+
customerPhone && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1495
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Phone, { className: "size-3 shrink-0", "aria-hidden": "true" }),
|
|
1201
1496
|
customerPhone
|
|
1202
1497
|
] }),
|
|
1203
|
-
customerEmail && /* @__PURE__ */ (0,
|
|
1204
|
-
/* @__PURE__ */ (0,
|
|
1205
|
-
/* @__PURE__ */ (0,
|
|
1498
|
+
customerEmail && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1499
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Mail, { className: "size-3 shrink-0", "aria-hidden": "true" }),
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate", children: customerEmail })
|
|
1206
1501
|
] })
|
|
1207
1502
|
] }),
|
|
1208
|
-
onDelete && /* @__PURE__ */ (0,
|
|
1209
|
-
/* @__PURE__ */ (0,
|
|
1503
|
+
onDelete && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(DropdownMenu, { children: [
|
|
1504
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1210
1505
|
DropdownMenuTrigger,
|
|
1211
1506
|
{
|
|
1212
1507
|
className: cn(
|
|
@@ -1214,10 +1509,10 @@ function LeadCard({
|
|
|
1214
1509
|
"-mr-1 -mt-1 size-7 shrink-0"
|
|
1215
1510
|
),
|
|
1216
1511
|
"aria-label": "Lead actions",
|
|
1217
|
-
children: /* @__PURE__ */ (0,
|
|
1512
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.MoreVertical, { className: "size-4" })
|
|
1218
1513
|
}
|
|
1219
1514
|
),
|
|
1220
|
-
/* @__PURE__ */ (0,
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1221
1516
|
DropdownMenuItem,
|
|
1222
1517
|
{
|
|
1223
1518
|
onClick: onDelete,
|
|
@@ -1227,9 +1522,9 @@ function LeadCard({
|
|
|
1227
1522
|
) })
|
|
1228
1523
|
] })
|
|
1229
1524
|
] }),
|
|
1230
|
-
/* @__PURE__ */ (0,
|
|
1231
|
-
onSendLoanApplication && /* @__PURE__ */ (0,
|
|
1232
|
-
/* @__PURE__ */ (0,
|
|
1525
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Separator, {}),
|
|
1526
|
+
onSendLoanApplication && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1233
1528
|
Button,
|
|
1234
1529
|
{
|
|
1235
1530
|
variant: "outline",
|
|
@@ -1240,10 +1535,10 @@ function LeadCard({
|
|
|
1240
1535
|
children: "Send Loan Application Request"
|
|
1241
1536
|
}
|
|
1242
1537
|
),
|
|
1243
|
-
loanApplicationUrl && /* @__PURE__ */ (0,
|
|
1538
|
+
loanApplicationUrl && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|
|
1244
1539
|
"Or the link below to fill out the loan application directly.",
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1246
|
-
/* @__PURE__ */ (0,
|
|
1540
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("br", {}),
|
|
1541
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1247
1542
|
"a",
|
|
1248
1543
|
{
|
|
1249
1544
|
href: `https://${loanApplicationUrl.replace(/^https?:\/\//, "")}`,
|
|
@@ -1261,7 +1556,7 @@ function LeadCard({
|
|
|
1261
1556
|
}
|
|
1262
1557
|
|
|
1263
1558
|
// src/components/ui/kanban-column.tsx
|
|
1264
|
-
var
|
|
1559
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1265
1560
|
function formatTotalValue(value) {
|
|
1266
1561
|
return formatCurrency(value);
|
|
1267
1562
|
}
|
|
@@ -1317,7 +1612,7 @@ function KanbanColumn({
|
|
|
1317
1612
|
const cardId = e.dataTransfer.getData("text/plain");
|
|
1318
1613
|
if (cardId) onCardDrop(cardId);
|
|
1319
1614
|
}
|
|
1320
|
-
return /* @__PURE__ */ (0,
|
|
1615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1321
1616
|
"div",
|
|
1322
1617
|
{
|
|
1323
1618
|
className: cn(
|
|
@@ -1331,15 +1626,15 @@ function KanbanColumn({
|
|
|
1331
1626
|
}),
|
|
1332
1627
|
"data-slot": "kanban-column",
|
|
1333
1628
|
children: [
|
|
1334
|
-
/* @__PURE__ */ (0,
|
|
1335
|
-
/* @__PURE__ */ (0,
|
|
1336
|
-
/* @__PURE__ */ (0,
|
|
1337
|
-
/* @__PURE__ */ (0,
|
|
1629
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-2 border-b border-border bg-background px-3 py-3", children: [
|
|
1630
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("h2", { className: "text-sm font-semibold text-foreground", children: [
|
|
1632
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-muted-foreground", children: stage.count }),
|
|
1338
1633
|
" ",
|
|
1339
1634
|
stage.name
|
|
1340
1635
|
] }),
|
|
1341
|
-
hasMenu && /* @__PURE__ */ (0,
|
|
1342
|
-
/* @__PURE__ */ (0,
|
|
1636
|
+
hasMenu && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(DropdownMenu, { children: [
|
|
1637
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1343
1638
|
DropdownMenuTrigger,
|
|
1344
1639
|
{
|
|
1345
1640
|
className: cn(
|
|
@@ -1347,14 +1642,14 @@ function KanbanColumn({
|
|
|
1347
1642
|
"-mr-1 size-7 shrink-0"
|
|
1348
1643
|
),
|
|
1349
1644
|
"aria-label": "Column actions",
|
|
1350
|
-
children: /* @__PURE__ */ (0,
|
|
1645
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.MoreVertical, { className: "size-4" })
|
|
1351
1646
|
}
|
|
1352
1647
|
),
|
|
1353
|
-
/* @__PURE__ */ (0,
|
|
1354
|
-
onEditColumn && /* @__PURE__ */ (0,
|
|
1355
|
-
!isDefault && onDeleteColumn && /* @__PURE__ */ (0,
|
|
1356
|
-
onEditColumn && /* @__PURE__ */ (0,
|
|
1357
|
-
/* @__PURE__ */ (0,
|
|
1648
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(DropdownMenuContent, { align: "end", children: [
|
|
1649
|
+
onEditColumn && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DropdownMenuItem, { onClick: onEditColumn, children: "Edit column settings" }),
|
|
1650
|
+
!isDefault && onDeleteColumn && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
1651
|
+
onEditColumn && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DropdownMenuSeparator, {}),
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1358
1653
|
DropdownMenuItem,
|
|
1359
1654
|
{
|
|
1360
1655
|
onClick: onDeleteColumn,
|
|
@@ -1366,8 +1661,8 @@ function KanbanColumn({
|
|
|
1366
1661
|
] })
|
|
1367
1662
|
] })
|
|
1368
1663
|
] }),
|
|
1369
|
-
/* @__PURE__ */ (0,
|
|
1370
|
-
stage.growth != null ? /* @__PURE__ */ (0,
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1665
|
+
stage.growth != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1371
1666
|
Badge,
|
|
1372
1667
|
{
|
|
1373
1668
|
variant: "outline",
|
|
@@ -1377,11 +1672,11 @@ function KanbanColumn({
|
|
|
1377
1672
|
stage.growth
|
|
1378
1673
|
]
|
|
1379
1674
|
}
|
|
1380
|
-
) : /* @__PURE__ */ (0,
|
|
1381
|
-
/* @__PURE__ */ (0,
|
|
1675
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", {}),
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-xs font-medium tabular-nums text-muted-foreground", children: formatTotalValue(stage.totalValue) })
|
|
1382
1677
|
] })
|
|
1383
1678
|
] }),
|
|
1384
|
-
/* @__PURE__ */ (0,
|
|
1679
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1385
1680
|
"div",
|
|
1386
1681
|
{
|
|
1387
1682
|
className: cn(
|
|
@@ -1392,13 +1687,13 @@ function KanbanColumn({
|
|
|
1392
1687
|
onDragLeave: handleDragLeave,
|
|
1393
1688
|
onDrop: handleDrop,
|
|
1394
1689
|
children: [
|
|
1395
|
-
(isDropTarget || isDragOver) && /* @__PURE__ */ (0,
|
|
1690
|
+
(isDropTarget || isDragOver) && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "border border-dashed border-primary/40 bg-primary/5 px-3 py-2 text-center text-xs text-primary", children: [
|
|
1396
1691
|
"Drop here \u2192 ",
|
|
1397
1692
|
stage.name
|
|
1398
1693
|
] }),
|
|
1399
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
1694
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex flex-1 items-center justify-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Spinner, { className: "size-5 text-muted-foreground" }) }) : opportunities.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex flex-1 items-center justify-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-muted-foreground", children: "No opportunities in this stage" }) }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
1400
1695
|
opportunities.map(
|
|
1401
|
-
(opp) => onSendLoanApplication ? /* @__PURE__ */ (0,
|
|
1696
|
+
(opp) => onSendLoanApplication ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1402
1697
|
LeadCard,
|
|
1403
1698
|
{
|
|
1404
1699
|
id: opp.id,
|
|
@@ -1411,7 +1706,7 @@ function KanbanColumn({
|
|
|
1411
1706
|
isSubmitting: submittingOpportunityId === opp.id
|
|
1412
1707
|
},
|
|
1413
1708
|
opp.id
|
|
1414
|
-
) : /* @__PURE__ */ (0,
|
|
1709
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1415
1710
|
OpportunityCard,
|
|
1416
1711
|
__spreadProps(__spreadValues({}, opp), {
|
|
1417
1712
|
draggable: !!onCardDrop,
|
|
@@ -1433,12 +1728,12 @@ function KanbanColumn({
|
|
|
1433
1728
|
opp.id
|
|
1434
1729
|
)
|
|
1435
1730
|
),
|
|
1436
|
-
hasMore && /* @__PURE__ */ (0,
|
|
1731
|
+
hasMore && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1437
1732
|
"div",
|
|
1438
1733
|
{
|
|
1439
1734
|
ref: loaderRef,
|
|
1440
1735
|
className: "flex min-h-[50px] items-center justify-center",
|
|
1441
|
-
children: isLoadingMore && /* @__PURE__ */ (0,
|
|
1736
|
+
children: isLoadingMore && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Spinner, { className: "size-5 text-muted-foreground" })
|
|
1442
1737
|
}
|
|
1443
1738
|
)
|
|
1444
1739
|
] })
|
|
@@ -1451,7 +1746,7 @@ function KanbanColumn({
|
|
|
1451
1746
|
}
|
|
1452
1747
|
|
|
1453
1748
|
// src/components/ui/pipeline-board.tsx
|
|
1454
|
-
var
|
|
1749
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1455
1750
|
function Toolbar({
|
|
1456
1751
|
searchValue,
|
|
1457
1752
|
onSearchChange,
|
|
@@ -1460,10 +1755,10 @@ function Toolbar({
|
|
|
1460
1755
|
onFilterChange,
|
|
1461
1756
|
onRefresh
|
|
1462
1757
|
}) {
|
|
1463
|
-
return /* @__PURE__ */ (0,
|
|
1464
|
-
/* @__PURE__ */ (0,
|
|
1465
|
-
/* @__PURE__ */ (0,
|
|
1466
|
-
/* @__PURE__ */ (0,
|
|
1758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-wrap items-center gap-3 border-b border-border bg-background px-4 py-3", children: [
|
|
1759
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative w-56 shrink-0", children: [
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Search, { className: "absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
1761
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1467
1762
|
Input,
|
|
1468
1763
|
{
|
|
1469
1764
|
placeholder: "Search opportunities\u2026",
|
|
@@ -1472,7 +1767,7 @@ function Toolbar({
|
|
|
1472
1767
|
className: "h-8 pl-8 text-sm"
|
|
1473
1768
|
}
|
|
1474
1769
|
),
|
|
1475
|
-
searchValue && /* @__PURE__ */ (0,
|
|
1770
|
+
searchValue && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1476
1771
|
Button,
|
|
1477
1772
|
{
|
|
1478
1773
|
type: "button",
|
|
@@ -1481,11 +1776,11 @@ function Toolbar({
|
|
|
1481
1776
|
onClick: () => onSearchChange(""),
|
|
1482
1777
|
className: "absolute right-2 top-1/2 size-6 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
1483
1778
|
"aria-label": "Clear search",
|
|
1484
|
-
children: /* @__PURE__ */ (0,
|
|
1779
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { className: "size-3.5" })
|
|
1485
1780
|
}
|
|
1486
1781
|
)
|
|
1487
1782
|
] }),
|
|
1488
|
-
filterOptions.length > 0 && /* @__PURE__ */ (0,
|
|
1783
|
+
filterOptions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1489
1784
|
ToggleGroup,
|
|
1490
1785
|
{
|
|
1491
1786
|
type: "multiple",
|
|
@@ -1498,10 +1793,10 @@ function Toolbar({
|
|
|
1498
1793
|
const toggled = (_a = newValues.find((v) => !activeFilters.includes(v))) != null ? _a : activeFilters.find((v) => !newValues.includes(v));
|
|
1499
1794
|
if (toggled) onFilterChange(toggled);
|
|
1500
1795
|
},
|
|
1501
|
-
children: filterOptions.map((option) => /* @__PURE__ */ (0,
|
|
1796
|
+
children: filterOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToggleGroupItem, { value: option, children: option }, option))
|
|
1502
1797
|
}
|
|
1503
1798
|
),
|
|
1504
|
-
onRefresh && /* @__PURE__ */ (0,
|
|
1799
|
+
onRefresh && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1505
1800
|
Button,
|
|
1506
1801
|
{
|
|
1507
1802
|
type: "button",
|
|
@@ -1510,7 +1805,7 @@ function Toolbar({
|
|
|
1510
1805
|
onClick: onRefresh,
|
|
1511
1806
|
className: "ml-auto text-muted-foreground hover:text-foreground",
|
|
1512
1807
|
"aria-label": "Refresh board",
|
|
1513
|
-
children: /* @__PURE__ */ (0,
|
|
1808
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.RefreshCw, { className: "size-4" })
|
|
1514
1809
|
}
|
|
1515
1810
|
)
|
|
1516
1811
|
] });
|
|
@@ -1539,13 +1834,13 @@ function PipelineBoard({
|
|
|
1539
1834
|
className
|
|
1540
1835
|
}) {
|
|
1541
1836
|
const hasToolbar = onSearchChange || filterOptions.length > 0 && onFilterChange;
|
|
1542
|
-
return /* @__PURE__ */ (0,
|
|
1837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1543
1838
|
"div",
|
|
1544
1839
|
{
|
|
1545
1840
|
className: cn("flex h-full flex-col bg-muted/20", className),
|
|
1546
1841
|
"data-slot": "pipeline-board",
|
|
1547
1842
|
children: [
|
|
1548
|
-
hasToolbar && /* @__PURE__ */ (0,
|
|
1843
|
+
hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1549
1844
|
Toolbar,
|
|
1550
1845
|
{
|
|
1551
1846
|
searchValue,
|
|
@@ -1558,8 +1853,8 @@ function PipelineBoard({
|
|
|
1558
1853
|
onRefresh
|
|
1559
1854
|
}
|
|
1560
1855
|
),
|
|
1561
|
-
/* @__PURE__ */ (0,
|
|
1562
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
1856
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-1 gap-3 overflow-x-auto p-4", children: [
|
|
1857
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1563
1858
|
KanbanColumn,
|
|
1564
1859
|
{
|
|
1565
1860
|
stage: col.stage,
|
|
@@ -1588,7 +1883,7 @@ function PipelineBoard({
|
|
|
1588
1883
|
},
|
|
1589
1884
|
col.key
|
|
1590
1885
|
)),
|
|
1591
|
-
columns.length === 0 && /* @__PURE__ */ (0,
|
|
1886
|
+
columns.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-muted-foreground", children: "No columns to display." }) })
|
|
1592
1887
|
] })
|
|
1593
1888
|
]
|
|
1594
1889
|
}
|