@wealthx/shadcn 1.5.39 → 1.5.41
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 +12 -0
- package/dist/{chunk-MGIDYXOP.mjs → chunk-DWNLBUDC.mjs} +459 -67
- package/dist/{chunk-EFHPSKVF.mjs → chunk-EGM4DARZ.mjs} +110 -1
- package/dist/{chunk-R7M657QL.mjs → chunk-GIQGZFP6.mjs} +138 -46
- package/dist/{chunk-B5PSUONN.mjs → chunk-TF5TOVIM.mjs} +1 -1
- package/dist/{chunk-RRROLESJ.mjs → chunk-XHZONBL4.mjs} +1 -1
- package/dist/components/ui/ai-assistant-drawer.js +101 -0
- package/dist/components/ui/ai-assistant-drawer.mjs +2 -2
- package/dist/components/ui/ai-conversations/index.js +101 -0
- package/dist/components/ui/ai-conversations/index.mjs +2 -2
- package/dist/components/ui/chat-input-area.js +101 -0
- package/dist/components/ui/chat-input-area.mjs +1 -1
- package/dist/components/ui/policy-ai/index.js +818 -261
- package/dist/components/ui/policy-ai/index.mjs +11 -2
- package/dist/components/ui/support-agent/index.js +233 -45
- package/dist/components/ui/support-agent/index.mjs +2 -2
- package/dist/index.js +3521 -3330
- package/dist/index.mjs +5 -5
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/ui/chat-input-area.tsx +181 -2
- package/src/components/ui/policy-ai/index.tsx +12 -0
- package/src/components/ui/policy-ai/policy-ai-context-sidebar.tsx +231 -0
- package/src/components/ui/policy-ai/policy-ai-history-panel.tsx +175 -0
- package/src/components/ui/policy-ai/policy-ai-page.tsx +243 -0
- package/src/components/ui/policy-ai/policy-ai-panel.tsx +64 -57
- package/src/components/ui/policy-ai/policy-ai-responses.tsx +8 -12
- package/src/components/ui/support-agent/support-agent-panel.tsx +170 -48
- package/src/styles/styles-css.ts +1 -1
|
@@ -59,7 +59,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
59
59
|
// src/components/ui/policy-ai/index.tsx
|
|
60
60
|
var policy_ai_exports = {};
|
|
61
61
|
__export(policy_ai_exports, {
|
|
62
|
+
PolicyAIContextSidebar: () => PolicyAIContextSidebar,
|
|
62
63
|
PolicyAIFAB: () => PolicyAIFAB,
|
|
64
|
+
PolicyAIHistoryPanel: () => PolicyAIHistoryPanel,
|
|
65
|
+
PolicyAIPage: () => PolicyAIPage,
|
|
63
66
|
PolicyAIPanel: () => PolicyAIPanel,
|
|
64
67
|
PolicyCitationPanel: () => PolicyCitationPanel,
|
|
65
68
|
PolicyComparisonTable: () => PolicyComparisonTable,
|
|
@@ -399,11 +402,52 @@ function PolicyCitationPanel({
|
|
|
399
402
|
var React5 = __toESM(require("react"));
|
|
400
403
|
var import_lucide_react3 = require("lucide-react");
|
|
401
404
|
|
|
402
|
-
// src/components/ui/
|
|
405
|
+
// src/components/ui/avatar.tsx
|
|
406
|
+
var import_avatar = require("@base-ui/react/avatar");
|
|
403
407
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
408
|
+
function Avatar(_a) {
|
|
409
|
+
var _b = _a, {
|
|
410
|
+
className,
|
|
411
|
+
size = "default"
|
|
412
|
+
} = _b, props = __objRest(_b, [
|
|
413
|
+
"className",
|
|
414
|
+
"size"
|
|
415
|
+
]);
|
|
416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
417
|
+
import_avatar.Avatar.Root,
|
|
418
|
+
__spreadValues({
|
|
419
|
+
className: cn(
|
|
420
|
+
"group/avatar relative flex size-8 shrink-0 rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
|
|
421
|
+
className
|
|
422
|
+
),
|
|
423
|
+
"data-size": size,
|
|
424
|
+
"data-slot": "avatar"
|
|
425
|
+
}, props)
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
function AvatarFallback(_a) {
|
|
429
|
+
var _b = _a, {
|
|
430
|
+
className
|
|
431
|
+
} = _b, props = __objRest(_b, [
|
|
432
|
+
"className"
|
|
433
|
+
]);
|
|
434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
435
|
+
import_avatar.Avatar.Fallback,
|
|
436
|
+
__spreadValues({
|
|
437
|
+
className: cn(
|
|
438
|
+
"flex size-full items-center justify-center rounded-full overflow-hidden bg-muted text-body-small font-sans text-muted-foreground group-data-[size=sm]/avatar:text-caption",
|
|
439
|
+
className
|
|
440
|
+
),
|
|
441
|
+
"data-slot": "avatar-fallback"
|
|
442
|
+
}, props)
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// src/components/ui/input.tsx
|
|
447
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
404
448
|
function Input(_a) {
|
|
405
449
|
var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
|
|
406
|
-
return /* @__PURE__ */ (0,
|
|
450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
407
451
|
"input",
|
|
408
452
|
__spreadValues({
|
|
409
453
|
className: cn(
|
|
@@ -423,21 +467,21 @@ var import_tooltip = require("@base-ui/react/tooltip");
|
|
|
423
467
|
|
|
424
468
|
// src/lib/theme-provider.tsx
|
|
425
469
|
var import_react2 = require("react");
|
|
426
|
-
var
|
|
470
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
427
471
|
var ThemeVarsContext = (0, import_react2.createContext)({});
|
|
428
472
|
function useThemeVars() {
|
|
429
473
|
return (0, import_react2.useContext)(ThemeVarsContext);
|
|
430
474
|
}
|
|
431
475
|
|
|
432
476
|
// src/components/ui/tooltip.tsx
|
|
433
|
-
var
|
|
477
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
434
478
|
function TooltipProvider(_a) {
|
|
435
479
|
var _b = _a, {
|
|
436
480
|
delay = 0
|
|
437
481
|
} = _b, props = __objRest(_b, [
|
|
438
482
|
"delay"
|
|
439
483
|
]);
|
|
440
|
-
return /* @__PURE__ */ (0,
|
|
484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
441
485
|
import_tooltip.Tooltip.Provider,
|
|
442
486
|
__spreadValues({
|
|
443
487
|
"data-slot": "tooltip-provider",
|
|
@@ -447,11 +491,11 @@ function TooltipProvider(_a) {
|
|
|
447
491
|
}
|
|
448
492
|
function Tooltip(_a) {
|
|
449
493
|
var props = __objRest(_a, []);
|
|
450
|
-
return /* @__PURE__ */ (0,
|
|
494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
|
|
451
495
|
}
|
|
452
496
|
function TooltipTrigger(_a) {
|
|
453
497
|
var props = __objRest(_a, []);
|
|
454
|
-
return /* @__PURE__ */ (0,
|
|
498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
|
|
455
499
|
}
|
|
456
500
|
function TooltipContent(_a) {
|
|
457
501
|
var _b = _a, {
|
|
@@ -468,7 +512,7 @@ function TooltipContent(_a) {
|
|
|
468
512
|
"style"
|
|
469
513
|
]);
|
|
470
514
|
const themeVars = useThemeVars();
|
|
471
|
-
return /* @__PURE__ */ (0,
|
|
515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
472
516
|
import_tooltip.Tooltip.Popup,
|
|
473
517
|
__spreadProps(__spreadValues({
|
|
474
518
|
className: cn(
|
|
@@ -480,7 +524,7 @@ function TooltipContent(_a) {
|
|
|
480
524
|
}, props), {
|
|
481
525
|
children: [
|
|
482
526
|
children,
|
|
483
|
-
/* @__PURE__ */ (0,
|
|
527
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.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" })
|
|
484
528
|
]
|
|
485
529
|
})
|
|
486
530
|
) }) });
|
|
@@ -489,15 +533,15 @@ function TooltipContent(_a) {
|
|
|
489
533
|
// src/components/ui/popover.tsx
|
|
490
534
|
var React4 = __toESM(require("react"));
|
|
491
535
|
var import_popover = require("@base-ui/react/popover");
|
|
492
|
-
var
|
|
536
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
493
537
|
var PopoverPortalContext = React4.createContext(void 0);
|
|
494
538
|
function Popover(_a) {
|
|
495
539
|
var props = __objRest(_a, []);
|
|
496
|
-
return /* @__PURE__ */ (0,
|
|
540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Root, __spreadValues({ "data-slot": "popover" }, props));
|
|
497
541
|
}
|
|
498
542
|
function PopoverTrigger(_a) {
|
|
499
543
|
var props = __objRest(_a, []);
|
|
500
|
-
return /* @__PURE__ */ (0,
|
|
544
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Trigger, __spreadValues({ "data-slot": "popover-trigger" }, props));
|
|
501
545
|
}
|
|
502
546
|
function PopoverContent(_a) {
|
|
503
547
|
var _b = _a, {
|
|
@@ -513,13 +557,13 @@ function PopoverContent(_a) {
|
|
|
513
557
|
]);
|
|
514
558
|
const themeVars = useThemeVars();
|
|
515
559
|
const portalContainer = React4.useContext(PopoverPortalContext);
|
|
516
|
-
return /* @__PURE__ */ (0,
|
|
560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_popover.Popover.Portal, { container: portalContainer != null ? portalContainer : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
517
561
|
import_popover.Popover.Positioner,
|
|
518
562
|
{
|
|
519
563
|
className: "z-[200]",
|
|
520
564
|
align,
|
|
521
565
|
sideOffset,
|
|
522
|
-
children: /* @__PURE__ */ (0,
|
|
566
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
523
567
|
import_popover.Popover.Popup,
|
|
524
568
|
__spreadValues({
|
|
525
569
|
className: cn(
|
|
@@ -536,7 +580,7 @@ function PopoverContent(_a) {
|
|
|
536
580
|
|
|
537
581
|
// src/components/ui/progress.tsx
|
|
538
582
|
var import_progress = require("@base-ui/react/progress");
|
|
539
|
-
var
|
|
583
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
540
584
|
function Progress(_a) {
|
|
541
585
|
var _b = _a, {
|
|
542
586
|
className,
|
|
@@ -547,14 +591,14 @@ function Progress(_a) {
|
|
|
547
591
|
"value",
|
|
548
592
|
"indicatorClassName"
|
|
549
593
|
]);
|
|
550
|
-
return /* @__PURE__ */ (0,
|
|
594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
551
595
|
import_progress.Progress.Root,
|
|
552
596
|
__spreadProps(__spreadValues({
|
|
553
597
|
className: cn("relative h-2 w-full overflow-hidden bg-muted", className),
|
|
554
598
|
"data-slot": "progress",
|
|
555
599
|
value
|
|
556
600
|
}, props), {
|
|
557
|
-
children: /* @__PURE__ */ (0,
|
|
601
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_progress.Progress.Track, { className: "h-full", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
558
602
|
import_progress.Progress.Indicator,
|
|
559
603
|
{
|
|
560
604
|
className: cn("h-full bg-primary transition-all", indicatorClassName),
|
|
@@ -568,7 +612,7 @@ function Progress(_a) {
|
|
|
568
612
|
// src/components/ui/tabs.tsx
|
|
569
613
|
var import_class_variance_authority3 = require("class-variance-authority");
|
|
570
614
|
var import_tabs = require("@base-ui/react/tabs");
|
|
571
|
-
var
|
|
615
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
572
616
|
function Tabs(_a) {
|
|
573
617
|
var _b = _a, {
|
|
574
618
|
className,
|
|
@@ -577,7 +621,7 @@ function Tabs(_a) {
|
|
|
577
621
|
"className",
|
|
578
622
|
"orientation"
|
|
579
623
|
]);
|
|
580
|
-
return /* @__PURE__ */ (0,
|
|
624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
581
625
|
import_tabs.Tabs.Root,
|
|
582
626
|
__spreadValues({
|
|
583
627
|
className: cn(
|
|
@@ -611,7 +655,7 @@ function TabsList(_a) {
|
|
|
611
655
|
"className",
|
|
612
656
|
"variant"
|
|
613
657
|
]);
|
|
614
|
-
return /* @__PURE__ */ (0,
|
|
658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
615
659
|
import_tabs.Tabs.List,
|
|
616
660
|
__spreadValues({
|
|
617
661
|
className: cn(tabsListVariants({ variant }), className),
|
|
@@ -622,7 +666,7 @@ function TabsList(_a) {
|
|
|
622
666
|
}
|
|
623
667
|
function TabsTrigger(_a) {
|
|
624
668
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
625
|
-
return /* @__PURE__ */ (0,
|
|
669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
626
670
|
import_tabs.Tabs.Tab,
|
|
627
671
|
__spreadValues({
|
|
628
672
|
className: cn(
|
|
@@ -659,28 +703,21 @@ function TabsTrigger(_a) {
|
|
|
659
703
|
}
|
|
660
704
|
|
|
661
705
|
// src/components/ui/policy-ai/policy-ai-responses.tsx
|
|
662
|
-
var
|
|
706
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
663
707
|
function BankAvatar({ name }) {
|
|
664
|
-
return /* @__PURE__ */ (0,
|
|
665
|
-
"span",
|
|
666
|
-
{
|
|
667
|
-
"aria-hidden": "true",
|
|
668
|
-
className: "shrink-0 inline-flex items-center justify-center size-7 bg-muted text-muted-foreground text-xs font-semibold border border-border",
|
|
669
|
-
children: name.charAt(0).toUpperCase()
|
|
670
|
-
}
|
|
671
|
-
);
|
|
708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Avatar, { "aria-hidden": "true", className: "size-7 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AvatarFallback, { children: name.charAt(0).toUpperCase() }) });
|
|
672
709
|
}
|
|
673
710
|
function QueryContextInfo({ label }) {
|
|
674
|
-
return /* @__PURE__ */ (0,
|
|
675
|
-
/* @__PURE__ */ (0,
|
|
711
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
676
713
|
"span",
|
|
677
714
|
{
|
|
678
715
|
className: "shrink-0 text-muted-foreground/60 hover:text-muted-foreground cursor-default transition-colors",
|
|
679
716
|
"aria-label": label,
|
|
680
|
-
children: /* @__PURE__ */ (0,
|
|
717
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Info, { className: "size-3.5", "aria-hidden": "true" })
|
|
681
718
|
}
|
|
682
719
|
) }),
|
|
683
|
-
/* @__PURE__ */ (0,
|
|
720
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipContent, { side: "top", children: label })
|
|
684
721
|
] }) });
|
|
685
722
|
}
|
|
686
723
|
function queryContextLabel(context) {
|
|
@@ -691,8 +728,8 @@ function queryContextLabel(context) {
|
|
|
691
728
|
].join(" \xB7 ");
|
|
692
729
|
}
|
|
693
730
|
function CitationBadge({ citation }) {
|
|
694
|
-
return /* @__PURE__ */ (0,
|
|
695
|
-
/* @__PURE__ */ (0,
|
|
731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Popover, { children: [
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": `View source ${citation.index}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
696
733
|
Badge,
|
|
697
734
|
{
|
|
698
735
|
variant: "secondary",
|
|
@@ -700,12 +737,12 @@ function CitationBadge({ citation }) {
|
|
|
700
737
|
children: citation.index
|
|
701
738
|
}
|
|
702
739
|
) }) }),
|
|
703
|
-
/* @__PURE__ */ (0,
|
|
704
|
-
/* @__PURE__ */ (0,
|
|
705
|
-
/* @__PURE__ */ (0,
|
|
706
|
-
/* @__PURE__ */ (0,
|
|
740
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverContent, { className: "w-72 p-3", sideOffset: 6, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
741
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
|
|
742
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-semibold text-foreground", children: citation.bankName }),
|
|
743
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "secondary", className: "text-xs px-1.5 py-0", children: citation.category })
|
|
707
744
|
] }),
|
|
708
|
-
/* @__PURE__ */ (0,
|
|
745
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-muted-foreground", children: citation.excerpt })
|
|
709
746
|
] }) })
|
|
710
747
|
] });
|
|
711
748
|
}
|
|
@@ -715,14 +752,14 @@ function AnswerWithCitations({
|
|
|
715
752
|
}) {
|
|
716
753
|
const citationMap = new Map(citations.map((c) => [c.index, c]));
|
|
717
754
|
const parts = answer.split(/(\[\d+\])/g);
|
|
718
|
-
return /* @__PURE__ */ (0,
|
|
755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-foreground leading-relaxed whitespace-pre-line", children: parts.map((part, i) => {
|
|
719
756
|
const match = part.match(/^\[(\d+)\]$/);
|
|
720
757
|
if (match) {
|
|
721
758
|
const citation = citationMap.get(parseInt(match[1], 10));
|
|
722
|
-
if (citation) return /* @__PURE__ */ (0,
|
|
723
|
-
return /* @__PURE__ */ (0,
|
|
759
|
+
if (citation) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CitationBadge, { citation }, i);
|
|
760
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-caption text-muted-foreground", children: part }, i);
|
|
724
761
|
}
|
|
725
|
-
return /* @__PURE__ */ (0,
|
|
762
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(React5.Fragment, { children: part }, i);
|
|
726
763
|
}) });
|
|
727
764
|
}
|
|
728
765
|
function PolicySingleBankAnswer({
|
|
@@ -733,21 +770,21 @@ function PolicySingleBankAnswer({
|
|
|
733
770
|
queryContext,
|
|
734
771
|
className
|
|
735
772
|
}) {
|
|
736
|
-
return /* @__PURE__ */ (0,
|
|
773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
737
774
|
"div",
|
|
738
775
|
{
|
|
739
776
|
"data-slot": "policy-single-bank-answer",
|
|
740
777
|
className: cn("border border-border bg-card flex flex-col", className),
|
|
741
778
|
children: [
|
|
742
|
-
/* @__PURE__ */ (0,
|
|
743
|
-
/* @__PURE__ */ (0,
|
|
744
|
-
/* @__PURE__ */ (0,
|
|
745
|
-
/* @__PURE__ */ (0,
|
|
746
|
-
queryContext && /* @__PURE__ */ (0,
|
|
779
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-border", children: [
|
|
780
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BankAvatar, { name: bankName }),
|
|
781
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 flex items-center gap-1.5 min-w-0", children: [
|
|
782
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-sm text-foreground truncate", children: bankName }),
|
|
783
|
+
queryContext && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
|
|
747
784
|
] }),
|
|
748
|
-
/* @__PURE__ */ (0,
|
|
785
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PolicyVerdictBadge, { verdict })
|
|
749
786
|
] }),
|
|
750
|
-
/* @__PURE__ */ (0,
|
|
787
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AnswerWithCitations, { answer, citations }) })
|
|
751
788
|
]
|
|
752
789
|
}
|
|
753
790
|
);
|
|
@@ -773,42 +810,42 @@ function PolicyComparisonTable({
|
|
|
773
810
|
}
|
|
774
811
|
return result;
|
|
775
812
|
}, [banks, search, filter]);
|
|
776
|
-
return /* @__PURE__ */ (0,
|
|
813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
777
814
|
"div",
|
|
778
815
|
{
|
|
779
816
|
"data-slot": "policy-comparison-table",
|
|
780
817
|
className: cn("border border-border bg-card flex flex-col", className),
|
|
781
818
|
children: [
|
|
782
|
-
/* @__PURE__ */ (0,
|
|
783
|
-
/* @__PURE__ */ (0,
|
|
819
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-border bg-muted/30", children: [
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
784
821
|
import_lucide_react3.Building2,
|
|
785
822
|
{
|
|
786
823
|
className: "size-3.5 text-muted-foreground shrink-0",
|
|
787
824
|
"aria-hidden": "true"
|
|
788
825
|
}
|
|
789
826
|
),
|
|
790
|
-
/* @__PURE__ */ (0,
|
|
791
|
-
/* @__PURE__ */ (0,
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-sm flex-wrap flex-1 min-w-0", children: [
|
|
828
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold text-foreground", children: [
|
|
792
829
|
summaryCounts.total,
|
|
793
830
|
" banks"
|
|
794
831
|
] }),
|
|
795
|
-
/* @__PURE__ */ (0,
|
|
796
|
-
/* @__PURE__ */ (0,
|
|
832
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-muted-foreground", children: "\xB7" }),
|
|
833
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Badge, { variant: "success", className: "text-xs px-1.5 py-0", children: [
|
|
797
834
|
summaryCounts.yes,
|
|
798
835
|
" Yes"
|
|
799
836
|
] }),
|
|
800
|
-
/* @__PURE__ */ (0,
|
|
837
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Badge, { variant: "warning", className: "text-xs px-1.5 py-0", children: [
|
|
801
838
|
summaryCounts.softNo,
|
|
802
839
|
" Soft No"
|
|
803
840
|
] }),
|
|
804
|
-
/* @__PURE__ */ (0,
|
|
841
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Badge, { variant: "destructive", className: "text-xs px-1.5 py-0", children: [
|
|
805
842
|
summaryCounts.no,
|
|
806
843
|
" No"
|
|
807
844
|
] })
|
|
808
845
|
] }),
|
|
809
|
-
queryContext && /* @__PURE__ */ (0,
|
|
846
|
+
queryContext && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
|
|
810
847
|
] }),
|
|
811
|
-
/* @__PURE__ */ (0,
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 py-2.5 border-b border-border", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
812
849
|
Input,
|
|
813
850
|
{
|
|
814
851
|
"aria-label": "Search banks",
|
|
@@ -818,23 +855,23 @@ function PolicyComparisonTable({
|
|
|
818
855
|
className: "h-8 text-sm"
|
|
819
856
|
}
|
|
820
857
|
) }),
|
|
821
|
-
/* @__PURE__ */ (0,
|
|
858
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-b border-border px-4 pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
822
859
|
Tabs,
|
|
823
860
|
{
|
|
824
861
|
value: filter,
|
|
825
862
|
onValueChange: (v) => setFilter(v),
|
|
826
|
-
children: /* @__PURE__ */ (0,
|
|
827
|
-
/* @__PURE__ */ (0,
|
|
828
|
-
/* @__PURE__ */ (0,
|
|
829
|
-
/* @__PURE__ */ (0,
|
|
830
|
-
/* @__PURE__ */ (0,
|
|
863
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(TabsList, { variant: "line", className: "justify-start h-8 gap-0 -mb-px", children: [
|
|
864
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "all", className: "text-sm px-3 h-7", children: "All" }),
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "yes", className: "text-sm px-3 h-7", children: "Yes" }),
|
|
866
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "soft_no", className: "text-sm px-3 h-7", children: "Soft No" }),
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TabsTrigger, { value: "no", className: "text-sm px-3 h-7", children: "No" })
|
|
831
868
|
] })
|
|
832
869
|
}
|
|
833
870
|
) }),
|
|
834
|
-
/* @__PURE__ */ (0,
|
|
835
|
-
/* @__PURE__ */ (0,
|
|
836
|
-
/* @__PURE__ */ (0,
|
|
837
|
-
categories.map((cat) => /* @__PURE__ */ (0,
|
|
871
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("table", { className: "w-full text-sm border-collapse", children: [
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { className: "border-b border-border bg-muted/20", children: [
|
|
873
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("th", { className: "text-left text-sm font-medium text-muted-foreground px-4 py-2", children: "Bank" }),
|
|
874
|
+
categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
838
875
|
"th",
|
|
839
876
|
{
|
|
840
877
|
className: "text-left text-sm font-medium text-muted-foreground px-3 py-2 w-px whitespace-nowrap",
|
|
@@ -843,26 +880,26 @@ function PolicyComparisonTable({
|
|
|
843
880
|
cat
|
|
844
881
|
))
|
|
845
882
|
] }) }),
|
|
846
|
-
/* @__PURE__ */ (0,
|
|
883
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tbody", { children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
847
884
|
"td",
|
|
848
885
|
{
|
|
849
886
|
colSpan: categories.length + 1,
|
|
850
887
|
className: "px-4 py-6 text-center text-sm text-muted-foreground",
|
|
851
888
|
children: "No banks match your search."
|
|
852
889
|
}
|
|
853
|
-
) }) : filtered.map((bank) => /* @__PURE__ */ (0,
|
|
854
|
-
/* @__PURE__ */ (0,
|
|
855
|
-
/* @__PURE__ */ (0,
|
|
856
|
-
/* @__PURE__ */ (0,
|
|
857
|
-
/* @__PURE__ */ (0,
|
|
858
|
-
bank.details && /* @__PURE__ */ (0,
|
|
890
|
+
) }) : filtered.map((bank) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { className: "border-b border-border", children: [
|
|
891
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
892
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BankAvatar, { name: bank.bankName }),
|
|
893
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
|
|
894
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-medium text-foreground leading-snug", children: bank.bankName }),
|
|
895
|
+
bank.details && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-caption text-muted-foreground", children: bank.details })
|
|
859
896
|
] })
|
|
860
897
|
] }) }),
|
|
861
|
-
categories.map((cat) => /* @__PURE__ */ (0,
|
|
898
|
+
categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
862
899
|
"td",
|
|
863
900
|
{
|
|
864
901
|
className: "px-3 py-2.5 align-top w-px whitespace-nowrap",
|
|
865
|
-
children: /* @__PURE__ */ (0,
|
|
902
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PolicyVerdictBadge, { verdict: bank.verdict })
|
|
866
903
|
},
|
|
867
904
|
cat
|
|
868
905
|
))
|
|
@@ -885,45 +922,45 @@ function PolicyRankedList({
|
|
|
885
922
|
queryContext,
|
|
886
923
|
className
|
|
887
924
|
}) {
|
|
888
|
-
return /* @__PURE__ */ (0,
|
|
925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
889
926
|
"div",
|
|
890
927
|
{
|
|
891
928
|
"data-slot": "policy-ranked-list",
|
|
892
929
|
className: cn("border border-border bg-card flex flex-col", className),
|
|
893
930
|
children: [
|
|
894
|
-
/* @__PURE__ */ (0,
|
|
895
|
-
/* @__PURE__ */ (0,
|
|
896
|
-
/* @__PURE__ */ (0,
|
|
897
|
-
i > 0 && /* @__PURE__ */ (0,
|
|
898
|
-
/* @__PURE__ */ (0,
|
|
931
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 px-4 py-2.5 border-b border-border bg-muted/30", children: [
|
|
932
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-muted-foreground shrink-0", children: "Ranked:" }),
|
|
933
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex items-center gap-1 flex-wrap flex-1 min-w-0", children: categories.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React5.Fragment, { children: [
|
|
934
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-muted-foreground", children: "+" }),
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "secondary", className: "text-xs px-1.5 py-0", children: cat })
|
|
899
936
|
] }, cat)) }),
|
|
900
|
-
/* @__PURE__ */ (0,
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-sm text-muted-foreground shrink-0", children: [
|
|
901
938
|
banks.length,
|
|
902
939
|
" banks"
|
|
903
940
|
] }),
|
|
904
|
-
queryContext && /* @__PURE__ */ (0,
|
|
941
|
+
queryContext && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueryContextInfo, { label: queryContextLabel(queryContext) })
|
|
905
942
|
] }),
|
|
906
|
-
/* @__PURE__ */ (0,
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "divide-y divide-border", children: banks.map((bank) => {
|
|
907
944
|
var _a, _b;
|
|
908
945
|
const scorePercent = Math.round(bank.score * 100);
|
|
909
|
-
return /* @__PURE__ */ (0,
|
|
910
|
-
/* @__PURE__ */ (0,
|
|
911
|
-
/* @__PURE__ */ (0,
|
|
946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col", children: [
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3", children: [
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "shrink-0 w-6 text-center text-sm font-bold text-muted-foreground", children: [
|
|
912
949
|
"#",
|
|
913
950
|
bank.rank
|
|
914
951
|
] }),
|
|
915
|
-
/* @__PURE__ */ (0,
|
|
916
|
-
/* @__PURE__ */ (0,
|
|
917
|
-
/* @__PURE__ */ (0,
|
|
918
|
-
/* @__PURE__ */ (0,
|
|
919
|
-
/* @__PURE__ */ (0,
|
|
952
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-1.5", children: [
|
|
953
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
954
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-medium text-foreground truncate", children: bank.bankName }),
|
|
955
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
956
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-sm text-muted-foreground font-mono", children: [
|
|
920
957
|
scorePercent,
|
|
921
958
|
"%"
|
|
922
959
|
] }),
|
|
923
|
-
/* @__PURE__ */ (0,
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PolicyVerdictBadge, { verdict: bank.verdict })
|
|
924
961
|
] })
|
|
925
962
|
] }),
|
|
926
|
-
/* @__PURE__ */ (0,
|
|
963
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
927
964
|
Progress,
|
|
928
965
|
{
|
|
929
966
|
value: scorePercent,
|
|
@@ -937,7 +974,7 @@ function PolicyRankedList({
|
|
|
937
974
|
)
|
|
938
975
|
] })
|
|
939
976
|
] }),
|
|
940
|
-
bank.highlights.length > 0 && /* @__PURE__ */ (0,
|
|
977
|
+
bank.highlights.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 pb-3 pl-[52px]", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "flex flex-col gap-0.5", children: bank.highlights.map((h, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
941
978
|
"li",
|
|
942
979
|
{
|
|
943
980
|
className: "text-sm text-muted-foreground leading-relaxed list-disc list-inside",
|
|
@@ -956,15 +993,32 @@ function PolicyRankedList({
|
|
|
956
993
|
var React7 = __toESM(require("react"));
|
|
957
994
|
var import_lucide_react6 = require("lucide-react");
|
|
958
995
|
|
|
996
|
+
// src/components/ui/card.tsx
|
|
997
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
998
|
+
function Card(_a) {
|
|
999
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
1000
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1001
|
+
"div",
|
|
1002
|
+
__spreadValues({
|
|
1003
|
+
className: cn(
|
|
1004
|
+
"flex flex-col gap-6 border bg-card py-6 text-card-foreground shadow-sm",
|
|
1005
|
+
className
|
|
1006
|
+
),
|
|
1007
|
+
"data-slot": "card"
|
|
1008
|
+
}, props)
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
959
1012
|
// src/components/ui/chat-input-area.tsx
|
|
960
1013
|
var React6 = __toESM(require("react"));
|
|
1014
|
+
var import_react_dom = require("react-dom");
|
|
961
1015
|
var import_lucide_react4 = require("lucide-react");
|
|
962
1016
|
|
|
963
1017
|
// src/components/ui/textarea.tsx
|
|
964
|
-
var
|
|
1018
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
965
1019
|
function Textarea(_a) {
|
|
966
1020
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
967
|
-
return /* @__PURE__ */ (0,
|
|
1021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
968
1022
|
"textarea",
|
|
969
1023
|
__spreadValues({
|
|
970
1024
|
className: cn(
|
|
@@ -978,8 +1032,99 @@ function Textarea(_a) {
|
|
|
978
1032
|
}
|
|
979
1033
|
|
|
980
1034
|
// src/components/ui/chat-input-area.tsx
|
|
981
|
-
var
|
|
1035
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
982
1036
|
var DEFAULT_HINT = "Enter to send \xB7 Shift+Enter for new line";
|
|
1037
|
+
var TOOLBAR_ITEMS = [
|
|
1038
|
+
{
|
|
1039
|
+
type: "button",
|
|
1040
|
+
icon: import_lucide_react4.Bold,
|
|
1041
|
+
label: "Bold",
|
|
1042
|
+
title: "Bold (Ctrl+B)",
|
|
1043
|
+
before: "**",
|
|
1044
|
+
after: "**",
|
|
1045
|
+
placeholder: "bold text"
|
|
1046
|
+
},
|
|
1047
|
+
{
|
|
1048
|
+
type: "button",
|
|
1049
|
+
icon: import_lucide_react4.Italic,
|
|
1050
|
+
label: "Italic",
|
|
1051
|
+
title: "Italic (Ctrl+I)",
|
|
1052
|
+
before: "*",
|
|
1053
|
+
after: "*",
|
|
1054
|
+
placeholder: "italic text"
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
type: "button",
|
|
1058
|
+
icon: import_lucide_react4.Code,
|
|
1059
|
+
label: "Inline code",
|
|
1060
|
+
title: "Inline code",
|
|
1061
|
+
before: "`",
|
|
1062
|
+
after: "`",
|
|
1063
|
+
placeholder: "code"
|
|
1064
|
+
},
|
|
1065
|
+
{ type: "divider" },
|
|
1066
|
+
{
|
|
1067
|
+
type: "button",
|
|
1068
|
+
icon: import_lucide_react4.Code2,
|
|
1069
|
+
label: "Code block",
|
|
1070
|
+
title: "Code block",
|
|
1071
|
+
before: "```\n",
|
|
1072
|
+
after: "\n```",
|
|
1073
|
+
placeholder: "code block"
|
|
1074
|
+
}
|
|
1075
|
+
];
|
|
1076
|
+
function applyMarkdown(textarea, before, after, placeholder, onChange) {
|
|
1077
|
+
const start = textarea.selectionStart;
|
|
1078
|
+
const end = textarea.selectionEnd;
|
|
1079
|
+
const selected = textarea.value.slice(start, end);
|
|
1080
|
+
const insertion = selected || placeholder;
|
|
1081
|
+
const next = textarea.value.slice(0, start) + before + insertion + after + textarea.value.slice(end);
|
|
1082
|
+
const newStart = start + before.length;
|
|
1083
|
+
const newEnd = newStart + insertion.length;
|
|
1084
|
+
(0, import_react_dom.flushSync)(() => onChange(next));
|
|
1085
|
+
textarea.focus();
|
|
1086
|
+
textarea.setSelectionRange(newStart, newEnd);
|
|
1087
|
+
}
|
|
1088
|
+
var MarkdownToolbar = React6.memo(function MarkdownToolbar2({
|
|
1089
|
+
textareaRef,
|
|
1090
|
+
onChange,
|
|
1091
|
+
disabled
|
|
1092
|
+
}) {
|
|
1093
|
+
const handleFormat = React6.useCallback(
|
|
1094
|
+
(e) => {
|
|
1095
|
+
if (!textareaRef.current) return;
|
|
1096
|
+
const { before, after, placeholder } = e.currentTarget.dataset;
|
|
1097
|
+
applyMarkdown(textareaRef.current, before, after, placeholder, onChange);
|
|
1098
|
+
},
|
|
1099
|
+
[textareaRef, onChange]
|
|
1100
|
+
);
|
|
1101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex items-center gap-0.5 border-b border-border px-2 py-1", children: TOOLBAR_ITEMS.map(
|
|
1102
|
+
(item, i) => item.type === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1103
|
+
"span",
|
|
1104
|
+
{
|
|
1105
|
+
className: "mx-0.5 h-3.5 w-px bg-border",
|
|
1106
|
+
"aria-hidden": "true"
|
|
1107
|
+
},
|
|
1108
|
+
i
|
|
1109
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1110
|
+
Button,
|
|
1111
|
+
{
|
|
1112
|
+
variant: "ghost",
|
|
1113
|
+
size: "icon-sm",
|
|
1114
|
+
type: "button",
|
|
1115
|
+
title: item.title,
|
|
1116
|
+
"aria-label": item.label,
|
|
1117
|
+
disabled,
|
|
1118
|
+
"data-before": item.before,
|
|
1119
|
+
"data-after": item.after,
|
|
1120
|
+
"data-placeholder": item.placeholder,
|
|
1121
|
+
onClick: handleFormat,
|
|
1122
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(item.icon, { className: "size-3.5", "aria-hidden": "true" })
|
|
1123
|
+
},
|
|
1124
|
+
item.label
|
|
1125
|
+
)
|
|
1126
|
+
) });
|
|
1127
|
+
});
|
|
983
1128
|
function ChatInputArea({
|
|
984
1129
|
value,
|
|
985
1130
|
onChange,
|
|
@@ -991,6 +1136,7 @@ function ChatInputArea({
|
|
|
991
1136
|
hint = DEFAULT_HINT,
|
|
992
1137
|
maxHeight = 160,
|
|
993
1138
|
autoFocus = false,
|
|
1139
|
+
showMarkdownToolbar = false,
|
|
994
1140
|
className
|
|
995
1141
|
}) {
|
|
996
1142
|
const textareaRef = React6.useRef(null);
|
|
@@ -1052,14 +1198,22 @@ function ChatInputArea({
|
|
|
1052
1198
|
);
|
|
1053
1199
|
const showFileButton = typeof onAttachFile === "function";
|
|
1054
1200
|
const showImageButton = typeof onAttachImage === "function";
|
|
1055
|
-
return /* @__PURE__ */ (0,
|
|
1201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1056
1202
|
"div",
|
|
1057
1203
|
{
|
|
1058
1204
|
"data-slot": "chat-input-area",
|
|
1059
1205
|
className: cn("flex flex-col gap-1.5", className),
|
|
1060
1206
|
children: [
|
|
1061
|
-
/* @__PURE__ */ (0,
|
|
1062
|
-
/* @__PURE__ */ (0,
|
|
1207
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "border border-border bg-background flex flex-col focus-within:ring-1 focus-within:ring-ring", children: [
|
|
1208
|
+
showMarkdownToolbar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1209
|
+
MarkdownToolbar,
|
|
1210
|
+
{
|
|
1211
|
+
textareaRef,
|
|
1212
|
+
onChange,
|
|
1213
|
+
disabled
|
|
1214
|
+
}
|
|
1215
|
+
),
|
|
1216
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1063
1217
|
Textarea,
|
|
1064
1218
|
{
|
|
1065
1219
|
ref: textareaRef,
|
|
@@ -1073,10 +1227,10 @@ function ChatInputArea({
|
|
|
1073
1227
|
"aria-label": placeholder
|
|
1074
1228
|
}
|
|
1075
1229
|
),
|
|
1076
|
-
/* @__PURE__ */ (0,
|
|
1077
|
-
/* @__PURE__ */ (0,
|
|
1078
|
-
showFileButton && /* @__PURE__ */ (0,
|
|
1079
|
-
/* @__PURE__ */ (0,
|
|
1230
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between px-2 pb-2", children: [
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-0.5", children: [
|
|
1232
|
+
showFileButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1233
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1080
1234
|
Button,
|
|
1081
1235
|
{
|
|
1082
1236
|
variant: "ghost",
|
|
@@ -1089,10 +1243,10 @@ function ChatInputArea({
|
|
|
1089
1243
|
var _a;
|
|
1090
1244
|
return (_a = fileInputRef.current) == null ? void 0 : _a.click();
|
|
1091
1245
|
},
|
|
1092
|
-
children: /* @__PURE__ */ (0,
|
|
1246
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.Paperclip, { className: "size-3.5", "aria-hidden": "true" })
|
|
1093
1247
|
}
|
|
1094
1248
|
),
|
|
1095
|
-
/* @__PURE__ */ (0,
|
|
1249
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1096
1250
|
"input",
|
|
1097
1251
|
{
|
|
1098
1252
|
ref: fileInputRef,
|
|
@@ -1104,8 +1258,8 @@ function ChatInputArea({
|
|
|
1104
1258
|
}
|
|
1105
1259
|
)
|
|
1106
1260
|
] }),
|
|
1107
|
-
showImageButton && /* @__PURE__ */ (0,
|
|
1108
|
-
/* @__PURE__ */ (0,
|
|
1261
|
+
showImageButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1262
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1109
1263
|
Button,
|
|
1110
1264
|
{
|
|
1111
1265
|
variant: "ghost",
|
|
@@ -1118,10 +1272,10 @@ function ChatInputArea({
|
|
|
1118
1272
|
var _a;
|
|
1119
1273
|
return (_a = imageInputRef.current) == null ? void 0 : _a.click();
|
|
1120
1274
|
},
|
|
1121
|
-
children: /* @__PURE__ */ (0,
|
|
1275
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.ImagePlus, { className: "size-3.5", "aria-hidden": "true" })
|
|
1122
1276
|
}
|
|
1123
1277
|
),
|
|
1124
|
-
/* @__PURE__ */ (0,
|
|
1278
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1125
1279
|
"input",
|
|
1126
1280
|
{
|
|
1127
1281
|
ref: imageInputRef,
|
|
@@ -1135,7 +1289,7 @@ function ChatInputArea({
|
|
|
1135
1289
|
)
|
|
1136
1290
|
] })
|
|
1137
1291
|
] }),
|
|
1138
|
-
/* @__PURE__ */ (0,
|
|
1292
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1139
1293
|
Button,
|
|
1140
1294
|
{
|
|
1141
1295
|
size: "icon-sm",
|
|
@@ -1143,12 +1297,12 @@ function ChatInputArea({
|
|
|
1143
1297
|
"aria-label": "Send message",
|
|
1144
1298
|
disabled: !value.trim() || disabled,
|
|
1145
1299
|
onClick: handleSend,
|
|
1146
|
-
children: /* @__PURE__ */ (0,
|
|
1300
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.Send, { className: "size-3.5", "aria-hidden": "true" })
|
|
1147
1301
|
}
|
|
1148
1302
|
)
|
|
1149
1303
|
] })
|
|
1150
1304
|
] }),
|
|
1151
|
-
hint !== false && /* @__PURE__ */ (0,
|
|
1305
|
+
hint !== false && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-xs text-muted-foreground", children: hint })
|
|
1152
1306
|
]
|
|
1153
1307
|
}
|
|
1154
1308
|
);
|
|
@@ -1156,50 +1310,7 @@ function ChatInputArea({
|
|
|
1156
1310
|
|
|
1157
1311
|
// src/components/ui/chat-widget-primitives.tsx
|
|
1158
1312
|
var import_lucide_react5 = require("lucide-react");
|
|
1159
|
-
|
|
1160
|
-
// src/components/ui/avatar.tsx
|
|
1161
|
-
var import_avatar = require("@base-ui/react/avatar");
|
|
1162
|
-
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1163
|
-
function Avatar(_a) {
|
|
1164
|
-
var _b = _a, {
|
|
1165
|
-
className,
|
|
1166
|
-
size = "default"
|
|
1167
|
-
} = _b, props = __objRest(_b, [
|
|
1168
|
-
"className",
|
|
1169
|
-
"size"
|
|
1170
|
-
]);
|
|
1171
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1172
|
-
import_avatar.Avatar.Root,
|
|
1173
|
-
__spreadValues({
|
|
1174
|
-
className: cn(
|
|
1175
|
-
"group/avatar relative flex size-8 shrink-0 rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
|
|
1176
|
-
className
|
|
1177
|
-
),
|
|
1178
|
-
"data-size": size,
|
|
1179
|
-
"data-slot": "avatar"
|
|
1180
|
-
}, props)
|
|
1181
|
-
);
|
|
1182
|
-
}
|
|
1183
|
-
function AvatarFallback(_a) {
|
|
1184
|
-
var _b = _a, {
|
|
1185
|
-
className
|
|
1186
|
-
} = _b, props = __objRest(_b, [
|
|
1187
|
-
"className"
|
|
1188
|
-
]);
|
|
1189
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1190
|
-
import_avatar.Avatar.Fallback,
|
|
1191
|
-
__spreadValues({
|
|
1192
|
-
className: cn(
|
|
1193
|
-
"flex size-full items-center justify-center rounded-full overflow-hidden bg-muted text-body-small font-sans text-muted-foreground group-data-[size=sm]/avatar:text-caption",
|
|
1194
|
-
className
|
|
1195
|
-
),
|
|
1196
|
-
"data-slot": "avatar-fallback"
|
|
1197
|
-
}, props)
|
|
1198
|
-
);
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
// src/components/ui/chat-widget-primitives.tsx
|
|
1202
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1313
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1203
1314
|
function ChatWidgetMessage({
|
|
1204
1315
|
role,
|
|
1205
1316
|
content,
|
|
@@ -1208,10 +1319,10 @@ function ChatWidgetMessage({
|
|
|
1208
1319
|
className
|
|
1209
1320
|
}) {
|
|
1210
1321
|
if (role === "system") {
|
|
1211
|
-
return /* @__PURE__ */ (0,
|
|
1322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("flex items-center justify-center py-2", className), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-body-small text-muted-foreground", children: content }) });
|
|
1212
1323
|
}
|
|
1213
1324
|
const isLeft = role === "bot" || role === "advisor";
|
|
1214
|
-
return /* @__PURE__ */ (0,
|
|
1325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1215
1326
|
"div",
|
|
1216
1327
|
{
|
|
1217
1328
|
className: cn(
|
|
@@ -1220,14 +1331,14 @@ function ChatWidgetMessage({
|
|
|
1220
1331
|
className
|
|
1221
1332
|
),
|
|
1222
1333
|
children: [
|
|
1223
|
-
isLeft && /* @__PURE__ */ (0,
|
|
1334
|
+
isLeft && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Avatar, { className: "size-7", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1224
1335
|
AvatarFallback,
|
|
1225
1336
|
{
|
|
1226
1337
|
className: role === "advisor" ? "bg-primary/15 text-foreground" : void 0,
|
|
1227
|
-
children: role === "advisor" ? /* @__PURE__ */ (0,
|
|
1338
|
+
children: role === "advisor" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.UserRound, { className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Bot, { className: "size-3.5" })
|
|
1228
1339
|
}
|
|
1229
1340
|
) }),
|
|
1230
|
-
/* @__PURE__ */ (0,
|
|
1341
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1231
1342
|
"div",
|
|
1232
1343
|
{
|
|
1233
1344
|
className: cn(
|
|
@@ -1235,7 +1346,7 @@ function ChatWidgetMessage({
|
|
|
1235
1346
|
!isLeft && "items-end"
|
|
1236
1347
|
),
|
|
1237
1348
|
children: [
|
|
1238
|
-
/* @__PURE__ */ (0,
|
|
1349
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1239
1350
|
"div",
|
|
1240
1351
|
{
|
|
1241
1352
|
className: cn(
|
|
@@ -1243,10 +1354,10 @@ function ChatWidgetMessage({
|
|
|
1243
1354
|
isLeft ? "border border-border bg-card text-card-foreground shadow-sm" : "text-primary-foreground"
|
|
1244
1355
|
),
|
|
1245
1356
|
style: !isLeft ? { backgroundColor: "var(--primary)" } : void 0,
|
|
1246
|
-
children: isStreaming ? /* @__PURE__ */ (0,
|
|
1357
|
+
children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChatWidgetTypingIndicator, {}) : content
|
|
1247
1358
|
}
|
|
1248
1359
|
),
|
|
1249
|
-
timestamp && !isStreaming && /* @__PURE__ */ (0,
|
|
1360
|
+
timestamp && !isStreaming && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[10px] text-muted-foreground", children: timestamp })
|
|
1250
1361
|
]
|
|
1251
1362
|
}
|
|
1252
1363
|
)
|
|
@@ -1257,13 +1368,13 @@ function ChatWidgetMessage({
|
|
|
1257
1368
|
function ChatWidgetTypingIndicator({
|
|
1258
1369
|
className
|
|
1259
1370
|
}) {
|
|
1260
|
-
return /* @__PURE__ */ (0,
|
|
1371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1261
1372
|
"div",
|
|
1262
1373
|
{
|
|
1263
1374
|
role: "status",
|
|
1264
1375
|
"aria-label": "Typing",
|
|
1265
1376
|
className: cn("flex items-center gap-1 py-0.5", className),
|
|
1266
|
-
children: [0, 1, 2].map((i) => /* @__PURE__ */ (0,
|
|
1377
|
+
children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1267
1378
|
"span",
|
|
1268
1379
|
{
|
|
1269
1380
|
className: "size-1.5 animate-bounce rounded-full bg-muted-foreground/60",
|
|
@@ -1277,7 +1388,7 @@ function ChatWidgetTypingIndicator({
|
|
|
1277
1388
|
}
|
|
1278
1389
|
|
|
1279
1390
|
// src/components/ui/policy-ai/policy-ai-panel.tsx
|
|
1280
|
-
var
|
|
1391
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1281
1392
|
var DEFAULT_SUGGESTED = {
|
|
1282
1393
|
Income: [
|
|
1283
1394
|
"Which banks accept casual income?",
|
|
@@ -1321,11 +1432,11 @@ function PolicyAIThinkingSteps({ steps }) {
|
|
|
1321
1432
|
const timer = setTimeout(() => setCurrentStep((s) => s + 1), 1400);
|
|
1322
1433
|
return () => clearTimeout(timer);
|
|
1323
1434
|
}, [currentStep, steps.length]);
|
|
1324
|
-
return /* @__PURE__ */ (0,
|
|
1435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-col gap-2.5 px-4 py-3", children: steps.map((step, i) => {
|
|
1325
1436
|
const isDone = i < currentStep;
|
|
1326
1437
|
const isCurrent = i === currentStep;
|
|
1327
1438
|
const isPending = i > currentStep;
|
|
1328
|
-
return /* @__PURE__ */ (0,
|
|
1439
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1329
1440
|
"div",
|
|
1330
1441
|
{
|
|
1331
1442
|
className: cn(
|
|
@@ -1333,12 +1444,12 @@ function PolicyAIThinkingSteps({ steps }) {
|
|
|
1333
1444
|
isPending && "opacity-30"
|
|
1334
1445
|
),
|
|
1335
1446
|
children: [
|
|
1336
|
-
/* @__PURE__ */ (0,
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "shrink-0 size-4 flex items-center justify-center", children: isDone ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Check, { className: "size-3.5 text-primary", "aria-hidden": "true" }) : isCurrent ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1337
1448
|
"span",
|
|
1338
1449
|
{
|
|
1339
1450
|
className: "flex items-center gap-0.5",
|
|
1340
1451
|
"aria-label": "In progress",
|
|
1341
|
-
children: [0, 1, 2].map((j) => /* @__PURE__ */ (0,
|
|
1452
|
+
children: [0, 1, 2].map((j) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1342
1453
|
"span",
|
|
1343
1454
|
{
|
|
1344
1455
|
className: "size-1 bg-muted-foreground/70 animate-bounce",
|
|
@@ -1348,7 +1459,7 @@ function PolicyAIThinkingSteps({ steps }) {
|
|
|
1348
1459
|
))
|
|
1349
1460
|
}
|
|
1350
1461
|
) : null }),
|
|
1351
|
-
/* @__PURE__ */ (0,
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1352
1463
|
"span",
|
|
1353
1464
|
{
|
|
1354
1465
|
className: cn(
|
|
@@ -1371,7 +1482,7 @@ function ResponseCard({
|
|
|
1371
1482
|
queryContext
|
|
1372
1483
|
}) {
|
|
1373
1484
|
if (content.type === "single_bank") {
|
|
1374
|
-
return /* @__PURE__ */ (0,
|
|
1485
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1375
1486
|
PolicySingleBankAnswer,
|
|
1376
1487
|
{
|
|
1377
1488
|
bankName: content.bankName,
|
|
@@ -1383,7 +1494,7 @@ function ResponseCard({
|
|
|
1383
1494
|
);
|
|
1384
1495
|
}
|
|
1385
1496
|
if (content.type === "cross_bank_comparison") {
|
|
1386
|
-
return /* @__PURE__ */ (0,
|
|
1497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1387
1498
|
PolicyComparisonTable,
|
|
1388
1499
|
{
|
|
1389
1500
|
categories: content.categories,
|
|
@@ -1395,7 +1506,7 @@ function ResponseCard({
|
|
|
1395
1506
|
);
|
|
1396
1507
|
}
|
|
1397
1508
|
if (content.type === "ranked_list") {
|
|
1398
|
-
return /* @__PURE__ */ (0,
|
|
1509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1399
1510
|
PolicyRankedList,
|
|
1400
1511
|
{
|
|
1401
1512
|
categories: content.categories,
|
|
@@ -1412,8 +1523,8 @@ function PolicyAIFAB({
|
|
|
1412
1523
|
hasNudge,
|
|
1413
1524
|
className
|
|
1414
1525
|
}) {
|
|
1415
|
-
return /* @__PURE__ */ (0,
|
|
1416
|
-
/* @__PURE__ */ (0,
|
|
1526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cn("relative inline-flex shrink-0", className), children: [
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1417
1528
|
Button,
|
|
1418
1529
|
{
|
|
1419
1530
|
"data-slot": "policy-ai-fab",
|
|
@@ -1421,14 +1532,14 @@ function PolicyAIFAB({
|
|
|
1421
1532
|
onClick,
|
|
1422
1533
|
className: "size-12 shadow-lg rounded-full",
|
|
1423
1534
|
"aria-label": "Open Policy AI",
|
|
1424
|
-
children: /* @__PURE__ */ (0,
|
|
1535
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.BrainCircuit, { className: "size-5", "aria-hidden": "true" })
|
|
1425
1536
|
}
|
|
1426
1537
|
),
|
|
1427
|
-
hasNudge && /* @__PURE__ */ (0,
|
|
1538
|
+
hasNudge && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "absolute -top-1 -right-1 size-3 bg-destructive rounded-full border-2 border-background" })
|
|
1428
1539
|
] });
|
|
1429
1540
|
}
|
|
1430
1541
|
function PolicyAIPanel({
|
|
1431
|
-
open,
|
|
1542
|
+
open = true,
|
|
1432
1543
|
onClose,
|
|
1433
1544
|
messages = [],
|
|
1434
1545
|
suggestedQuestions,
|
|
@@ -1466,7 +1577,7 @@ function PolicyAIPanel({
|
|
|
1466
1577
|
);
|
|
1467
1578
|
if (!open) return null;
|
|
1468
1579
|
const positionClass = position === "bottom-left" ? "left-6" : "right-6";
|
|
1469
|
-
return /* @__PURE__ */ (0,
|
|
1580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1470
1581
|
"div",
|
|
1471
1582
|
{
|
|
1472
1583
|
"data-slot": "policy-ai-panel",
|
|
@@ -1485,17 +1596,17 @@ function PolicyAIPanel({
|
|
|
1485
1596
|
maxHeight: minimised ? "auto" : "min(600px, calc(100vh - 120px))"
|
|
1486
1597
|
},
|
|
1487
1598
|
children: [
|
|
1488
|
-
!inline && /* @__PURE__ */ (0,
|
|
1489
|
-
/* @__PURE__ */ (0,
|
|
1599
|
+
!inline && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "shrink-0 flex items-center gap-2.5 px-3 py-2.5 border-b border-border bg-card", children: [
|
|
1600
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1490
1601
|
import_lucide_react6.BrainCircuit,
|
|
1491
1602
|
{
|
|
1492
1603
|
className: "size-4 text-primary shrink-0",
|
|
1493
1604
|
"aria-hidden": "true"
|
|
1494
1605
|
}
|
|
1495
1606
|
),
|
|
1496
|
-
/* @__PURE__ */ (0,
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1498
|
-
isChatMode && onReset && !minimised && /* @__PURE__ */ (0,
|
|
1607
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm font-semibold text-foreground flex-1 truncate", children: "Policy AI" }),
|
|
1608
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-0.5", children: [
|
|
1609
|
+
isChatMode && onReset && !minimised && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1499
1610
|
Button,
|
|
1500
1611
|
{
|
|
1501
1612
|
variant: "ghost",
|
|
@@ -1503,10 +1614,10 @@ function PolicyAIPanel({
|
|
|
1503
1614
|
onClick: onReset,
|
|
1504
1615
|
title: "New conversation",
|
|
1505
1616
|
"aria-label": "New conversation",
|
|
1506
|
-
children: /* @__PURE__ */ (0,
|
|
1617
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.RotateCcw, { className: "size-3.5", "aria-hidden": "true" })
|
|
1507
1618
|
}
|
|
1508
1619
|
),
|
|
1509
|
-
/* @__PURE__ */ (0,
|
|
1620
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1510
1621
|
Button,
|
|
1511
1622
|
{
|
|
1512
1623
|
variant: "ghost",
|
|
@@ -1514,10 +1625,10 @@ function PolicyAIPanel({
|
|
|
1514
1625
|
onClick: () => setMinimised((v) => !v),
|
|
1515
1626
|
title: minimised ? "Restore" : "Minimise",
|
|
1516
1627
|
"aria-label": minimised ? "Restore panel" : "Minimise panel",
|
|
1517
|
-
children: minimised ? /* @__PURE__ */ (0,
|
|
1628
|
+
children: minimised ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.ChevronDown, { className: "size-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.Minus, { className: "size-3.5", "aria-hidden": "true" })
|
|
1518
1629
|
}
|
|
1519
1630
|
),
|
|
1520
|
-
/* @__PURE__ */ (0,
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1521
1632
|
Button,
|
|
1522
1633
|
{
|
|
1523
1634
|
variant: "ghost",
|
|
@@ -1525,65 +1636,68 @@ function PolicyAIPanel({
|
|
|
1525
1636
|
onClick: onClose,
|
|
1526
1637
|
title: "Close",
|
|
1527
1638
|
"aria-label": "Close Policy AI",
|
|
1528
|
-
children: /* @__PURE__ */ (0,
|
|
1639
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.X, { className: "size-3.5", "aria-hidden": "true" })
|
|
1529
1640
|
}
|
|
1530
1641
|
)
|
|
1531
1642
|
] })
|
|
1532
1643
|
] }),
|
|
1533
|
-
(!minimised || inline) && /* @__PURE__ */ (0,
|
|
1534
|
-
/* @__PURE__ */ (0,
|
|
1644
|
+
(!minimised || inline) && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-col justify-center h-full py-8", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PolicyAIThinkingSteps, { steps: resolvedThinkingSteps }) }) : !isChatMode ? (
|
|
1535
1646
|
/* Home state — suggested questions by policy type */
|
|
1536
|
-
/* @__PURE__ */ (0,
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1539
|
-
|
|
1540
|
-
{
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1544
|
-
TabsList,
|
|
1647
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 px-3 py-3", children: [
|
|
1648
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-muted-foreground", children: "Ask me about lending policies across 40+ Australian banks \u2014 income, LVR, security types, serviceability, and more." }),
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-overline text-muted-foreground", children: "Suggested" }),
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Card, { className: "gap-0 py-0 shadow-none overflow-hidden", children: [
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "border-b border-border px-3 pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1653
|
+
Tabs,
|
|
1545
1654
|
{
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
children:
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1655
|
+
value: activeTab,
|
|
1656
|
+
onValueChange: (v) => setActiveTab(v),
|
|
1657
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1658
|
+
TabsList,
|
|
1659
|
+
{
|
|
1660
|
+
variant: "line",
|
|
1661
|
+
className: "justify-start h-8 gap-0 -mb-px overflow-x-auto",
|
|
1662
|
+
children: Object.keys(DEFAULT_SUGGESTED).map((type) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1663
|
+
TabsTrigger,
|
|
1664
|
+
{
|
|
1665
|
+
value: type,
|
|
1666
|
+
className: "px-2 h-7 shrink-0",
|
|
1667
|
+
children: type
|
|
1668
|
+
},
|
|
1669
|
+
type
|
|
1670
|
+
))
|
|
1671
|
+
}
|
|
1558
1672
|
)
|
|
1559
1673
|
}
|
|
1560
|
-
)
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1674
|
+
) }),
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "divide-y divide-border", children: ((_a = (suggestedQuestions != null ? suggestedQuestions : DEFAULT_SUGGESTED)[activeTab]) != null ? _a : []).map((q) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1676
|
+
"button",
|
|
1677
|
+
{
|
|
1678
|
+
onClick: () => setInputValue(q),
|
|
1679
|
+
className: "w-full text-left text-sm text-foreground px-3 py-2.5 hover:bg-muted/60 transition-colors",
|
|
1680
|
+
children: q
|
|
1681
|
+
},
|
|
1682
|
+
q
|
|
1683
|
+
)) })
|
|
1684
|
+
] })
|
|
1685
|
+
] })
|
|
1572
1686
|
] })
|
|
1573
1687
|
) : (
|
|
1574
1688
|
/* Chat state — messages + structured response cards */
|
|
1575
|
-
/* @__PURE__ */ (0,
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-4 px-3 py-3", children: [
|
|
1576
1690
|
messages.map(
|
|
1577
|
-
(msg) => msg.role === "user" ? /* @__PURE__ */ (0,
|
|
1691
|
+
(msg) => msg.role === "user" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1578
1692
|
ChatWidgetMessage,
|
|
1579
1693
|
{
|
|
1580
1694
|
role: "user",
|
|
1581
1695
|
content: msg.content
|
|
1582
1696
|
},
|
|
1583
1697
|
msg.id
|
|
1584
|
-
) : /* @__PURE__ */ (0,
|
|
1585
|
-
msg.content && /* @__PURE__ */ (0,
|
|
1586
|
-
msg.responseContent && /* @__PURE__ */ (0,
|
|
1698
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
1699
|
+
msg.content && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-foreground leading-relaxed", children: msg.content }),
|
|
1700
|
+
msg.responseContent && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1587
1701
|
ResponseCard,
|
|
1588
1702
|
{
|
|
1589
1703
|
content: msg.responseContent,
|
|
@@ -1592,30 +1706,470 @@ function PolicyAIPanel({
|
|
|
1592
1706
|
)
|
|
1593
1707
|
] }, msg.id)
|
|
1594
1708
|
),
|
|
1595
|
-
isStreaming && /* @__PURE__ */ (0,
|
|
1596
|
-
/* @__PURE__ */ (0,
|
|
1709
|
+
isStreaming && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PolicyAIThinkingSteps, { steps: resolvedThinkingSteps }),
|
|
1710
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: messagesEndRef })
|
|
1597
1711
|
] })
|
|
1598
1712
|
) }),
|
|
1599
|
-
!isLoading && /* @__PURE__ */ (0,
|
|
1600
|
-
|
|
1713
|
+
!isLoading && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "shrink-0 border-t border-border px-3 py-3 bg-card", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1714
|
+
ChatInputArea,
|
|
1601
1715
|
{
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1716
|
+
value: inputValue,
|
|
1717
|
+
onChange: setInputValue,
|
|
1718
|
+
onSend: handleSend,
|
|
1719
|
+
onAttachFile,
|
|
1720
|
+
onAttachImage,
|
|
1721
|
+
disabled: isStreaming,
|
|
1722
|
+
placeholder: "Ask about lending policies\u2026",
|
|
1723
|
+
autoFocus: !minimised,
|
|
1724
|
+
showMarkdownToolbar: true
|
|
1725
|
+
}
|
|
1726
|
+
) })
|
|
1727
|
+
] })
|
|
1728
|
+
]
|
|
1729
|
+
}
|
|
1730
|
+
);
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
// src/components/ui/policy-ai/policy-ai-history-panel.tsx
|
|
1734
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1735
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1736
|
+
function PolicyAIHistoryItem({
|
|
1737
|
+
conv,
|
|
1738
|
+
isActive,
|
|
1739
|
+
onClick
|
|
1740
|
+
}) {
|
|
1741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1742
|
+
"button",
|
|
1743
|
+
{
|
|
1744
|
+
type: "button",
|
|
1745
|
+
onClick,
|
|
1746
|
+
className: cn(
|
|
1747
|
+
"w-full flex items-start gap-3 px-3 py-3 text-left transition-colors",
|
|
1748
|
+
"border-b border-border last:border-b-0",
|
|
1749
|
+
isActive ? "bg-muted" : "hover:bg-muted/40"
|
|
1750
|
+
),
|
|
1751
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1753
|
+
"span",
|
|
1754
|
+
{
|
|
1755
|
+
className: cn(
|
|
1756
|
+
"text-sm leading-snug line-clamp-2 min-w-0",
|
|
1757
|
+
isActive ? "font-semibold text-foreground" : "text-foreground"
|
|
1758
|
+
),
|
|
1759
|
+
children: conv.title
|
|
1760
|
+
}
|
|
1761
|
+
),
|
|
1762
|
+
conv.timestamp && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "shrink-0 text-caption text-muted-foreground whitespace-nowrap", children: conv.timestamp })
|
|
1763
|
+
] }) })
|
|
1764
|
+
}
|
|
1765
|
+
);
|
|
1766
|
+
}
|
|
1767
|
+
function PolicyAIHistoryPanel({
|
|
1768
|
+
conversations,
|
|
1769
|
+
activeId,
|
|
1770
|
+
onSelect,
|
|
1771
|
+
onNewChat,
|
|
1772
|
+
searchQuery = "",
|
|
1773
|
+
onSearchChange,
|
|
1774
|
+
className
|
|
1775
|
+
}) {
|
|
1776
|
+
const filtered = searchQuery ? conversations.filter(
|
|
1777
|
+
(c) => c.title.toLowerCase().includes(searchQuery.toLowerCase())
|
|
1778
|
+
) : conversations;
|
|
1779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1780
|
+
"div",
|
|
1781
|
+
{
|
|
1782
|
+
"data-slot": "policy-ai-history-panel",
|
|
1783
|
+
className: cn(
|
|
1784
|
+
"flex flex-col h-full border-r border-border bg-background shrink-0",
|
|
1785
|
+
className
|
|
1786
|
+
),
|
|
1787
|
+
children: [
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "shrink-0 flex flex-col", children: [
|
|
1789
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center gap-2 border-b border-border px-3 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1790
|
+
Button,
|
|
1791
|
+
{
|
|
1792
|
+
size: "sm",
|
|
1793
|
+
className: "w-full justify-start gap-2",
|
|
1794
|
+
onClick: onNewChat,
|
|
1795
|
+
children: [
|
|
1796
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1797
|
+
import_lucide_react7.MessageSquarePlus,
|
|
1798
|
+
{
|
|
1799
|
+
className: "size-3.5 shrink-0",
|
|
1800
|
+
"aria-hidden": "true"
|
|
1801
|
+
}
|
|
1802
|
+
),
|
|
1803
|
+
"New Chat"
|
|
1804
|
+
]
|
|
1805
|
+
}
|
|
1806
|
+
) }),
|
|
1807
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex items-center border-b border-border px-3 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative flex-1", children: [
|
|
1808
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1809
|
+
import_lucide_react7.Search,
|
|
1810
|
+
{
|
|
1811
|
+
className: "absolute left-2.5 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground pointer-events-none",
|
|
1812
|
+
"aria-hidden": "true"
|
|
1813
|
+
}
|
|
1814
|
+
),
|
|
1815
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1816
|
+
Input,
|
|
1817
|
+
{
|
|
1818
|
+
value: searchQuery,
|
|
1819
|
+
onChange: (e) => onSearchChange == null ? void 0 : onSearchChange(e.target.value),
|
|
1820
|
+
placeholder: "Search conversations...",
|
|
1821
|
+
className: "h-8 pl-8 text-sm",
|
|
1822
|
+
"aria-label": "Search conversations"
|
|
1823
|
+
}
|
|
1824
|
+
)
|
|
1825
|
+
] }) })
|
|
1826
|
+
] }),
|
|
1827
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 overflow-y-auto min-h-0", tabIndex: 0, children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col items-center justify-center gap-2 p-8 text-muted-foreground", children: [
|
|
1828
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.BrainCircuit, { className: "size-8 opacity-30", "aria-hidden": "true" }),
|
|
1829
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm", children: searchQuery ? "No conversations found." : "No recent sessions." }),
|
|
1830
|
+
searchQuery && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1831
|
+
Button,
|
|
1832
|
+
{
|
|
1833
|
+
variant: "outline",
|
|
1834
|
+
size: "sm",
|
|
1835
|
+
onClick: () => onSearchChange == null ? void 0 : onSearchChange(""),
|
|
1836
|
+
children: "Clear search"
|
|
1837
|
+
}
|
|
1838
|
+
)
|
|
1839
|
+
] }) : filtered.map((conv) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1840
|
+
PolicyAIHistoryItem,
|
|
1841
|
+
{
|
|
1842
|
+
conv,
|
|
1843
|
+
isActive: conv.id === activeId,
|
|
1844
|
+
onClick: () => onSelect == null ? void 0 : onSelect(conv.id)
|
|
1845
|
+
},
|
|
1846
|
+
conv.id
|
|
1847
|
+
)) })
|
|
1848
|
+
]
|
|
1849
|
+
}
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// src/components/ui/policy-ai/policy-ai-context-sidebar.tsx
|
|
1854
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1855
|
+
|
|
1856
|
+
// src/components/ui/separator.tsx
|
|
1857
|
+
var import_separator = require("@base-ui/react/separator");
|
|
1858
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1859
|
+
function Separator(_a) {
|
|
1860
|
+
var _b = _a, {
|
|
1861
|
+
className,
|
|
1862
|
+
orientation = "horizontal"
|
|
1863
|
+
} = _b, props = __objRest(_b, [
|
|
1864
|
+
"className",
|
|
1865
|
+
"orientation"
|
|
1866
|
+
]);
|
|
1867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1868
|
+
import_separator.Separator,
|
|
1869
|
+
__spreadValues({
|
|
1870
|
+
className: cn(
|
|
1871
|
+
"shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
|
1872
|
+
className
|
|
1873
|
+
),
|
|
1874
|
+
"data-orientation": orientation,
|
|
1875
|
+
"data-slot": "separator"
|
|
1876
|
+
}, props)
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
// src/components/ui/policy-ai/policy-ai-context-sidebar.tsx
|
|
1881
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1882
|
+
var QUERY_TYPE_DESCRIPTIONS = {
|
|
1883
|
+
single_bank: "Answered from a single bank's policy documents.",
|
|
1884
|
+
cross_bank_comparison: "Compared across all indexed banks simultaneously.",
|
|
1885
|
+
threshold_filter: "Filtered banks against a specific threshold or limit.",
|
|
1886
|
+
ranking: "Ranked banks using TOPSIS multi-criteria scoring.",
|
|
1887
|
+
scenario_match: "Matched your scenario against all bank lending criteria.",
|
|
1888
|
+
general: "General policy question answered from the knowledge base."
|
|
1889
|
+
};
|
|
1890
|
+
var QUERY_TYPE_LABELS2 = {
|
|
1891
|
+
single_bank: "Single bank",
|
|
1892
|
+
cross_bank_comparison: "Cross-bank",
|
|
1893
|
+
threshold_filter: "Threshold filter",
|
|
1894
|
+
ranking: "Ranked list",
|
|
1895
|
+
scenario_match: "Scenario match",
|
|
1896
|
+
general: "General"
|
|
1897
|
+
};
|
|
1898
|
+
function SidebarSection({
|
|
1899
|
+
title,
|
|
1900
|
+
children,
|
|
1901
|
+
className
|
|
1902
|
+
}) {
|
|
1903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-overline text-muted-foreground px-3", children: title }),
|
|
1905
|
+
children
|
|
1906
|
+
] });
|
|
1907
|
+
}
|
|
1908
|
+
function StatRow({
|
|
1909
|
+
icon: Icon,
|
|
1910
|
+
children
|
|
1911
|
+
}) {
|
|
1912
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
1913
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1914
|
+
Icon,
|
|
1915
|
+
{
|
|
1916
|
+
className: "size-3.5 text-muted-foreground shrink-0",
|
|
1917
|
+
"aria-hidden": "true"
|
|
1918
|
+
}
|
|
1919
|
+
),
|
|
1920
|
+
children
|
|
1921
|
+
] });
|
|
1922
|
+
}
|
|
1923
|
+
function PolicyAIContextSidebar({
|
|
1924
|
+
lastQueryContext,
|
|
1925
|
+
suggestedFollowUps,
|
|
1926
|
+
onFollowUpClick,
|
|
1927
|
+
bankCount = 42,
|
|
1928
|
+
categoryCount = 86,
|
|
1929
|
+
lastUpdated = "June 2026",
|
|
1930
|
+
className
|
|
1931
|
+
}) {
|
|
1932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1933
|
+
"div",
|
|
1934
|
+
{
|
|
1935
|
+
"data-slot": "policy-ai-context-sidebar",
|
|
1936
|
+
className: cn(
|
|
1937
|
+
"flex flex-col h-full border-l border-border bg-card shrink-0 overflow-y-auto",
|
|
1938
|
+
className
|
|
1939
|
+
),
|
|
1940
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-5 px-0 py-4", children: [
|
|
1941
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarSection, { title: "Coverage", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1.5 px-3", children: [
|
|
1942
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatRow, { icon: import_lucide_react8.BrainCircuit, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-sm text-foreground", children: [
|
|
1943
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "font-semibold", children: bankCount }),
|
|
1944
|
+
" banks indexed"
|
|
1945
|
+
] }) }),
|
|
1946
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatRow, { icon: import_lucide_react8.Layers, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-sm text-foreground", children: [
|
|
1947
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "font-semibold", children: categoryCount }),
|
|
1948
|
+
" policy categories"
|
|
1949
|
+
] }) }),
|
|
1950
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatRow, { icon: import_lucide_react8.Database, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-caption text-muted-foreground", children: [
|
|
1951
|
+
"Updated ",
|
|
1952
|
+
lastUpdated
|
|
1953
|
+
] }) })
|
|
1954
|
+
] }) }),
|
|
1955
|
+
lastQueryContext && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
1956
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Separator, {}),
|
|
1957
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarSection, { title: "Last Query", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Card, { className: "gap-0 py-0 shadow-none overflow-hidden mx-3", children: [
|
|
1958
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border bg-muted/30", children: [
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm font-semibold text-foreground", children: lastQueryContext.policyType }),
|
|
1960
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Badge, { variant: "outline", className: "text-xs shrink-0", children: QUERY_TYPE_LABELS2[lastQueryContext.queryType] })
|
|
1961
|
+
] }),
|
|
1962
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2 px-3 py-2.5", children: [
|
|
1963
|
+
lastQueryContext.bankName && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-semibold text-foreground leading-none", children: lastQueryContext.bankName }),
|
|
1964
|
+
lastQueryContext.categories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-wrap gap-1", children: lastQueryContext.categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1965
|
+
Badge,
|
|
1608
1966
|
{
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1967
|
+
variant: "secondary",
|
|
1968
|
+
className: "text-xs font-normal",
|
|
1969
|
+
children: cat
|
|
1970
|
+
},
|
|
1971
|
+
cat
|
|
1972
|
+
)) })
|
|
1973
|
+
] }),
|
|
1974
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "border-t border-border px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-caption text-muted-foreground leading-snug", children: QUERY_TYPE_DESCRIPTIONS[lastQueryContext.queryType] }) })
|
|
1975
|
+
] }) })
|
|
1976
|
+
] }),
|
|
1977
|
+
!!(suggestedFollowUps == null ? void 0 : suggestedFollowUps.length) && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
1978
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Separator, {}),
|
|
1979
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SidebarSection, { title: "Follow-ups", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-col gap-1 px-3", children: suggestedFollowUps.map((q) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1980
|
+
Button,
|
|
1981
|
+
{
|
|
1982
|
+
variant: "outline",
|
|
1983
|
+
size: "sm",
|
|
1984
|
+
className: "w-full justify-start h-auto py-1.5 text-muted-foreground font-normal leading-snug whitespace-normal text-left",
|
|
1985
|
+
onClick: () => onFollowUpClick == null ? void 0 : onFollowUpClick(q),
|
|
1986
|
+
children: q
|
|
1987
|
+
},
|
|
1988
|
+
q
|
|
1989
|
+
)) }) })
|
|
1990
|
+
] })
|
|
1991
|
+
] })
|
|
1992
|
+
}
|
|
1993
|
+
);
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
// src/components/ui/policy-ai/policy-ai-page.tsx
|
|
1997
|
+
var React8 = __toESM(require("react"));
|
|
1998
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1999
|
+
|
|
2000
|
+
// src/components/ui/page-top-bar.tsx
|
|
2001
|
+
var import_lucide_react9 = require("lucide-react");
|
|
2002
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2003
|
+
function PageTopBar({
|
|
2004
|
+
title,
|
|
2005
|
+
actions,
|
|
2006
|
+
onAskSupport,
|
|
2007
|
+
className
|
|
2008
|
+
}) {
|
|
2009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2010
|
+
"div",
|
|
2011
|
+
{
|
|
2012
|
+
"data-slot": "page-top-bar",
|
|
2013
|
+
className: cn(
|
|
2014
|
+
"flex shrink-0 items-center justify-between gap-4",
|
|
2015
|
+
"border-b border-border bg-background px-6 py-3",
|
|
2016
|
+
className
|
|
2017
|
+
),
|
|
2018
|
+
children: [
|
|
2019
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { className: "text-lg font-semibold leading-tight", children: title }),
|
|
2020
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2021
|
+
actions,
|
|
2022
|
+
onAskSupport && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Button, { variant: "outline", size: "sm", onClick: onAskSupport, children: [
|
|
2023
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Bot, { className: "size-3.5", "aria-hidden": "true" }),
|
|
2024
|
+
"Ask Support"
|
|
2025
|
+
] })
|
|
2026
|
+
] })
|
|
2027
|
+
]
|
|
2028
|
+
}
|
|
2029
|
+
);
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
// src/components/ui/policy-ai/policy-ai-page.tsx
|
|
2033
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2034
|
+
function deriveFollowUps(context) {
|
|
2035
|
+
var _a;
|
|
2036
|
+
if (!context) return [];
|
|
2037
|
+
const { queryType, policyType, bankName } = context;
|
|
2038
|
+
if (queryType === "cross_bank_comparison") {
|
|
2039
|
+
return [
|
|
2040
|
+
`Which of these banks is best overall for ${(_a = context.categories[0]) != null ? _a : policyType}?`,
|
|
2041
|
+
bankName ? `Does ${bankName} have any exceptions?` : "Which bank has the most flexible policy?",
|
|
2042
|
+
"Show me the ranked list of lenders."
|
|
2043
|
+
];
|
|
2044
|
+
}
|
|
2045
|
+
if (queryType === "ranking") {
|
|
2046
|
+
return [
|
|
2047
|
+
`What are the full details for the #1 ranked bank?`,
|
|
2048
|
+
`Which banks in the list accept cases under 80% LVR?`,
|
|
2049
|
+
`Compare the top 3 banks side by side.`
|
|
2050
|
+
];
|
|
2051
|
+
}
|
|
2052
|
+
if (queryType === "single_bank") {
|
|
2053
|
+
return [
|
|
2054
|
+
`How does ${bankName != null ? bankName : "this bank"} compare to other lenders?`,
|
|
2055
|
+
`What documentation does ${bankName != null ? bankName : "this bank"} require?`,
|
|
2056
|
+
`Which banks have a better policy than ${bankName != null ? bankName : "this bank"}?`
|
|
2057
|
+
];
|
|
2058
|
+
}
|
|
2059
|
+
if (queryType === "threshold_filter") {
|
|
2060
|
+
return [
|
|
2061
|
+
`What is the maximum LVR across all filtered banks?`,
|
|
2062
|
+
`Are any of these banks on a specialist product?`,
|
|
2063
|
+
`Rank the filtered banks best to worst.`
|
|
2064
|
+
];
|
|
2065
|
+
}
|
|
2066
|
+
return [];
|
|
2067
|
+
}
|
|
2068
|
+
function PolicyAIPage({
|
|
2069
|
+
// Chat
|
|
2070
|
+
messages = [],
|
|
2071
|
+
suggestedQuestions,
|
|
2072
|
+
isStreaming = false,
|
|
2073
|
+
isLoading = false,
|
|
2074
|
+
thinkingSteps,
|
|
2075
|
+
onSendMessage,
|
|
2076
|
+
onAttachFile,
|
|
2077
|
+
onAttachImage,
|
|
2078
|
+
onReset,
|
|
2079
|
+
// History
|
|
2080
|
+
conversations = [],
|
|
2081
|
+
activeConversationId,
|
|
2082
|
+
onSelectConversation,
|
|
2083
|
+
onNewChat,
|
|
2084
|
+
// Context
|
|
2085
|
+
defaultShowContextPanel = true,
|
|
2086
|
+
bankCount = 42,
|
|
2087
|
+
categoryCount = 86,
|
|
2088
|
+
lastUpdated = "June 2026",
|
|
2089
|
+
onAskSupport,
|
|
2090
|
+
className
|
|
2091
|
+
}) {
|
|
2092
|
+
const [showContextPanel, setShowContextPanel] = React8.useState(
|
|
2093
|
+
defaultShowContextPanel
|
|
2094
|
+
);
|
|
2095
|
+
const [historySearch, setHistorySearch] = React8.useState("");
|
|
2096
|
+
const lastQueryContext = React8.useMemo(() => {
|
|
2097
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2098
|
+
const m = messages[i];
|
|
2099
|
+
if (m.role === "assistant" && m.queryContext) return m.queryContext;
|
|
2100
|
+
}
|
|
2101
|
+
return void 0;
|
|
2102
|
+
}, [messages]);
|
|
2103
|
+
const followUps = deriveFollowUps(lastQueryContext);
|
|
2104
|
+
const handleNewChat = () => {
|
|
2105
|
+
onReset == null ? void 0 : onReset();
|
|
2106
|
+
onNewChat == null ? void 0 : onNewChat();
|
|
2107
|
+
};
|
|
2108
|
+
const panelToggleLabel = showContextPanel ? "Hide context panel" : "Show context panel";
|
|
2109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2110
|
+
"div",
|
|
2111
|
+
{
|
|
2112
|
+
"data-slot": "policy-ai-page",
|
|
2113
|
+
className: cn("flex flex-col h-full bg-background", className),
|
|
2114
|
+
children: [
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2116
|
+
PageTopBar,
|
|
2117
|
+
{
|
|
2118
|
+
title: "Policy AI",
|
|
2119
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2120
|
+
Button,
|
|
2121
|
+
{
|
|
2122
|
+
variant: "ghost",
|
|
2123
|
+
size: "icon-sm",
|
|
2124
|
+
onClick: () => setShowContextPanel((v) => !v),
|
|
2125
|
+
"aria-label": panelToggleLabel,
|
|
2126
|
+
"aria-pressed": showContextPanel,
|
|
2127
|
+
title: panelToggleLabel,
|
|
2128
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.PanelRight, { className: "size-4", "aria-hidden": "true" })
|
|
2129
|
+
}
|
|
2130
|
+
),
|
|
2131
|
+
onAskSupport
|
|
2132
|
+
}
|
|
2133
|
+
),
|
|
2134
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-1 min-h-0 overflow-hidden", children: [
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2136
|
+
PolicyAIHistoryPanel,
|
|
2137
|
+
{
|
|
2138
|
+
conversations,
|
|
2139
|
+
activeId: activeConversationId,
|
|
2140
|
+
onSelect: onSelectConversation,
|
|
2141
|
+
onNewChat: handleNewChat,
|
|
2142
|
+
searchQuery: historySearch,
|
|
2143
|
+
onSearchChange: setHistorySearch,
|
|
2144
|
+
className: "w-[260px]"
|
|
2145
|
+
}
|
|
2146
|
+
),
|
|
2147
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 flex flex-col min-w-0 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2148
|
+
PolicyAIPanel,
|
|
2149
|
+
{
|
|
2150
|
+
inline: true,
|
|
2151
|
+
messages,
|
|
2152
|
+
suggestedQuestions,
|
|
2153
|
+
isStreaming,
|
|
2154
|
+
isLoading,
|
|
2155
|
+
thinkingSteps,
|
|
2156
|
+
onSendMessage,
|
|
2157
|
+
onAttachFile,
|
|
2158
|
+
onAttachImage,
|
|
2159
|
+
onReset,
|
|
2160
|
+
className: "flex-1 min-h-0"
|
|
2161
|
+
}
|
|
2162
|
+
) }),
|
|
2163
|
+
showContextPanel && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2164
|
+
PolicyAIContextSidebar,
|
|
2165
|
+
{
|
|
2166
|
+
lastQueryContext,
|
|
2167
|
+
suggestedFollowUps: followUps,
|
|
2168
|
+
onFollowUpClick: onSendMessage,
|
|
2169
|
+
bankCount,
|
|
2170
|
+
categoryCount,
|
|
2171
|
+
lastUpdated,
|
|
2172
|
+
className: "w-[280px]"
|
|
1619
2173
|
}
|
|
1620
2174
|
)
|
|
1621
2175
|
] })
|
|
@@ -1625,7 +2179,10 @@ function PolicyAIPanel({
|
|
|
1625
2179
|
}
|
|
1626
2180
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1627
2181
|
0 && (module.exports = {
|
|
2182
|
+
PolicyAIContextSidebar,
|
|
1628
2183
|
PolicyAIFAB,
|
|
2184
|
+
PolicyAIHistoryPanel,
|
|
2185
|
+
PolicyAIPage,
|
|
1629
2186
|
PolicyAIPanel,
|
|
1630
2187
|
PolicyCitationPanel,
|
|
1631
2188
|
PolicyComparisonTable,
|