@wealthx/shadcn 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +235 -138
- package/CHANGELOG.md +12 -0
- package/README.md +82 -0
- package/dist/{chunk-6OJF6XRN.mjs → chunk-24FUO7TD.mjs} +4 -8
- package/dist/{chunk-4AJ5HWHD.mjs → chunk-2I5S2AMY.mjs} +3 -3
- package/dist/chunk-2SF672SZ.mjs +161 -0
- package/dist/{chunk-GPRJQ24C.mjs → chunk-34NWQURD.mjs} +2 -2
- package/dist/{chunk-MQ72DIBH.mjs → chunk-3GF7OVTP.mjs} +14 -5
- package/dist/chunk-3WMX6KWS.mjs +245 -0
- package/dist/{chunk-PMKODV6M.mjs → chunk-462HMNO4.mjs} +6 -10
- package/dist/chunk-4CX4SBRO.mjs +153 -0
- package/dist/chunk-4MN6UQHG.mjs +443 -0
- package/dist/chunk-5QQVZTVZ.mjs +233 -0
- package/dist/{chunk-BGP2N52Z.mjs → chunk-66MI7Q4B.mjs} +5 -5
- package/dist/chunk-6FCGKSZX.mjs +268 -0
- package/dist/{chunk-CGOKTPXU.mjs → chunk-6JQFUE5I.mjs} +20 -23
- package/dist/{chunk-Z3MK2KKZ.mjs → chunk-7DHU4VGG.mjs} +7 -3
- package/dist/{chunk-VZ2NR7L3.mjs → chunk-7PYJD5JI.mjs} +35 -27
- package/dist/{chunk-JU2RUWHF.mjs → chunk-7XJHLGUV.mjs} +1 -1
- package/dist/{chunk-BMFN37JH.mjs → chunk-7YAU5CY6.mjs} +1 -1
- package/dist/chunk-A56YQQHG.mjs +402 -0
- package/dist/chunk-AH52LG6N.mjs +315 -0
- package/dist/{chunk-SLWCCURD.mjs → chunk-CLIN5525.mjs} +8 -4
- package/dist/{chunk-3VQNJ235.mjs → chunk-CSDO6VBW.mjs} +7 -0
- package/dist/chunk-D4ILTPOG.mjs +293 -0
- package/dist/{chunk-HS7TFG7V.mjs → chunk-D6ID6M4V.mjs} +1 -1
- package/dist/chunk-DOH3EHX7.mjs +378 -0
- package/dist/{chunk-MJIEMGRD.mjs → chunk-EFRENWEJ.mjs} +9 -17
- package/dist/chunk-ERGGHC2V.mjs +185 -0
- package/dist/{chunk-OXQQNQZI.mjs → chunk-FEZKMUCF.mjs} +10 -1
- package/dist/{chunk-55CEW76V.mjs → chunk-FH6QVUVZ.mjs} +1 -1
- package/dist/chunk-FMAXJ2SI.mjs +71 -0
- package/dist/chunk-FZIXGLMV.mjs +173 -0
- package/dist/{chunk-DS2AMHN2.mjs → chunk-GYMYRIZP.mjs} +2 -2
- package/dist/{chunk-KQDD5MU3.mjs → chunk-H45TKD34.mjs} +5 -5
- package/dist/{chunk-BBJBJSXQ.mjs → chunk-J5UICVJS.mjs} +1 -1
- package/dist/{chunk-RL772EH7.mjs → chunk-JHJHG4GO.mjs} +4 -12
- package/dist/chunk-KMCGSZTX.mjs +177 -0
- package/dist/{chunk-FHNT55I5.mjs → chunk-KUDCQ4FI.mjs} +4 -4
- package/dist/chunk-LE6YFY6D.mjs +209 -0
- package/dist/{chunk-HUVTPUV2.mjs → chunk-LLVQKSU3.mjs} +23 -19
- package/dist/{chunk-KKHTJNMM.mjs → chunk-MARPPFOJ.mjs} +8 -4
- package/dist/{chunk-6AFMNC42.mjs → chunk-N2PT566P.mjs} +15 -11
- package/dist/chunk-NLCKVHWB.mjs +161 -0
- package/dist/{chunk-YN5SYTOO.mjs → chunk-NQPOYKAQ.mjs} +9 -5
- package/dist/{chunk-ZZV5JVNW.mjs → chunk-NSLMILBT.mjs} +3 -7
- package/dist/chunk-NXA3CZ7A.mjs +248 -0
- package/dist/chunk-OGOYQ7BG.mjs +150 -0
- package/dist/{chunk-3NQGYJEZ.mjs → chunk-P6AM5V7O.mjs} +10 -18
- package/dist/{chunk-CZ3BW5GL.mjs → chunk-P76HMUI6.mjs} +5 -11
- package/dist/chunk-PCPLO5HT.mjs +671 -0
- package/dist/chunk-PG6K5XEC.mjs +475 -0
- package/dist/chunk-PJHPSRYD.mjs +234 -0
- package/dist/{chunk-DDPA2XXS.mjs → chunk-PMB3A7V3.mjs} +2 -2
- package/dist/chunk-PR6V5XKM.mjs +209 -0
- package/dist/{chunk-46OFHMQA.mjs → chunk-Q76O3RIQ.mjs} +10 -6
- package/dist/chunk-QVKWW6KE.mjs +272 -0
- package/dist/chunk-RGU7HOEC.mjs +140 -0
- package/dist/{chunk-JF4PHPD5.mjs → chunk-RGVKLTLH.mjs} +4 -4
- package/dist/{chunk-VG6UF6UT.mjs → chunk-RP3SQYA3.mjs} +2 -2
- package/dist/chunk-RRBS6D63.mjs +163 -0
- package/dist/chunk-SMQ3DG25.mjs +285 -0
- package/dist/chunk-SPJ5KXW7.mjs +199 -0
- package/dist/chunk-SYOD63OZ.mjs +225 -0
- package/dist/chunk-UFYSFDER.mjs +42 -0
- package/dist/chunk-VACKZOMY.mjs +190 -0
- package/dist/chunk-VLQZANBF.mjs +42 -0
- package/dist/chunk-WA6O6EUR.mjs +1885 -0
- package/dist/{chunk-E3K6O4FZ.mjs → chunk-WAZD7NFU.mjs} +5 -2
- package/dist/chunk-WG6JGJXB.mjs +165 -0
- package/dist/{chunk-I64K754C.mjs → chunk-WNGWBVLV.mjs} +2 -2
- package/dist/{chunk-3U7SD3MS.mjs → chunk-WOEHFRGB.mjs} +3 -3
- package/dist/{chunk-DKZRJOMF.mjs → chunk-XIRTEFKH.mjs} +12 -12
- package/dist/chunk-Y6DWJSKZ.mjs +79 -0
- package/dist/chunk-YKPROFLB.mjs +161 -0
- package/dist/{chunk-K76E2TQU.mjs → chunk-ZRO5JO3H.mjs} +107 -67
- package/dist/{chunk-VYMHBV6D.mjs → chunk-ZU4NV6RG.mjs} +5 -3
- package/dist/components/ui/accordion.js +40 -4
- package/dist/components/ui/accordion.mjs +2 -2
- package/dist/components/ui/add-column-modal.js +789 -0
- package/dist/components/ui/add-column-modal.mjs +17 -0
- package/dist/components/ui/add-lead-modal.js +647 -0
- package/dist/components/ui/add-lead-modal.mjs +16 -0
- package/dist/components/ui/ai-assistant-drawer.js +686 -0
- package/dist/components/ui/ai-assistant-drawer.mjs +16 -0
- package/dist/components/ui/alert-dialog.js +37 -5
- package/dist/components/ui/alert-dialog.mjs +4 -4
- package/dist/components/ui/alert.js +37 -11
- package/dist/components/ui/alert.mjs +2 -2
- package/dist/components/ui/avatar.js +36 -8
- package/dist/components/ui/avatar.mjs +2 -2
- package/dist/components/ui/backoffice-alert-history-chart.js +624 -0
- package/dist/components/ui/backoffice-alert-history-chart.mjs +16 -0
- package/dist/components/ui/backoffice-contact-history-chart.js +687 -0
- package/dist/components/ui/backoffice-contact-history-chart.mjs +16 -0
- package/dist/components/ui/badge.js +37 -2
- package/dist/components/ui/badge.mjs +2 -2
- package/dist/components/ui/borrowing-capacity-line-chart.js +639 -0
- package/dist/components/ui/borrowing-capacity-line-chart.mjs +16 -0
- package/dist/components/ui/button.js +35 -3
- package/dist/components/ui/button.mjs +2 -2
- package/dist/components/ui/calendar.js +43 -19
- package/dist/components/ui/calendar.mjs +3 -3
- package/dist/components/ui/card.js +40 -4
- package/dist/components/ui/card.mjs +2 -2
- package/dist/components/ui/cash-balance-line-chart.js +627 -0
- package/dist/components/ui/cash-balance-line-chart.mjs +16 -0
- package/dist/components/ui/cashflow-bar-chart.js +650 -0
- package/dist/components/ui/cashflow-bar-chart.mjs +16 -0
- package/dist/components/ui/checkbox.js +36 -5
- package/dist/components/ui/checkbox.mjs +2 -3
- package/dist/components/ui/chip.js +37 -2
- package/dist/components/ui/chip.mjs +3 -3
- package/dist/components/ui/combobox.js +280 -0
- package/dist/components/ui/combobox.mjs +28 -0
- package/dist/components/ui/data-table.js +160 -88
- package/dist/components/ui/data-table.mjs +10 -11
- package/dist/components/ui/date-picker.js +44 -20
- package/dist/components/ui/date-picker.mjs +6 -7
- package/dist/components/ui/dialog.js +44 -12
- package/dist/components/ui/dialog.mjs +4 -4
- package/dist/components/ui/drawer.js +46 -10
- package/dist/components/ui/drawer.mjs +3 -3
- package/dist/components/ui/dropdown-menu.js +40 -16
- package/dist/components/ui/dropdown-menu.mjs +3 -3
- package/dist/components/ui/empty.js +41 -5
- package/dist/components/ui/empty.mjs +2 -2
- package/dist/components/ui/expense-bar-chart.js +642 -0
- package/dist/components/ui/expense-bar-chart.mjs +16 -0
- package/dist/components/ui/field.js +53 -21
- package/dist/components/ui/field.mjs +4 -4
- package/dist/components/ui/financial-cards.js +1002 -0
- package/dist/components/ui/financial-cards.mjs +24 -0
- package/dist/components/ui/financial-drawers.js +637 -0
- package/dist/components/ui/financial-drawers.mjs +17 -0
- package/dist/components/ui/financial-primitives.js +218 -0
- package/dist/components/ui/financial-primitives.mjs +22 -0
- package/dist/components/ui/financial-sections.js +1422 -0
- package/dist/components/ui/financial-sections.mjs +30 -0
- package/dist/components/ui/form-primitives.js +682 -0
- package/dist/components/ui/form-primitives.mjs +19 -0
- package/dist/components/ui/income-bar-chart.js +641 -0
- package/dist/components/ui/income-bar-chart.mjs +16 -0
- package/dist/components/ui/input-group.js +43 -7
- package/dist/components/ui/input-group.mjs +5 -5
- package/dist/components/ui/input-otp.js +39 -3
- package/dist/components/ui/input-otp.mjs +2 -2
- package/dist/components/ui/input.js +34 -2
- package/dist/components/ui/input.mjs +2 -2
- package/dist/components/ui/kanban-column.js +1143 -0
- package/dist/components/ui/kanban-column.mjs +20 -0
- package/dist/components/ui/label.js +35 -7
- package/dist/components/ui/label.mjs +2 -2
- package/dist/components/ui/opportunity-card.js +960 -0
- package/dist/components/ui/opportunity-card.mjs +20 -0
- package/dist/components/ui/opportunity-edit-modals.js +3360 -0
- package/dist/components/ui/opportunity-edit-modals.mjs +37 -0
- package/dist/components/ui/opportunity-summary-tab.js +4365 -0
- package/dist/components/ui/opportunity-summary-tab.mjs +34 -0
- package/dist/components/ui/pagination.js +35 -3
- package/dist/components/ui/pagination.mjs +3 -3
- package/dist/components/ui/pipeline-alerts.js +103 -0
- package/dist/components/ui/pipeline-alerts.mjs +8 -0
- package/dist/components/ui/pipeline-board.js +1408 -0
- package/dist/components/ui/pipeline-board.mjs +24 -0
- package/dist/components/ui/pipeline-chart.js +216 -0
- package/dist/components/ui/pipeline-chart.mjs +10 -0
- package/dist/components/ui/pipeline-dialogs.js +1183 -0
- package/dist/components/ui/pipeline-dialogs.mjs +23 -0
- package/dist/components/ui/pipeline-primitives.js +300 -0
- package/dist/components/ui/pipeline-primitives.mjs +11 -0
- package/dist/components/ui/popover.js +45 -4
- package/dist/components/ui/popover.mjs +3 -3
- package/dist/components/ui/progress.js +33 -1
- package/dist/components/ui/progress.mjs +2 -2
- package/dist/components/ui/property-cashflow-doughnut-chart.js +523 -0
- package/dist/components/ui/property-cashflow-doughnut-chart.mjs +16 -0
- package/dist/components/ui/property-debt-equity-doughnut-chart.js +521 -0
- package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +16 -0
- package/dist/components/ui/property-mobile-estimate-line-chart.js +682 -0
- package/dist/components/ui/property-mobile-estimate-line-chart.mjs +16 -0
- package/dist/components/ui/radio-group.js +33 -1
- package/dist/components/ui/radio-group.mjs +2 -2
- package/dist/components/ui/select.js +66 -26
- package/dist/components/ui/select.mjs +3 -3
- package/dist/components/ui/separator.js +33 -1
- package/dist/components/ui/separator.mjs +2 -2
- package/dist/components/ui/sheet.js +37 -9
- package/dist/components/ui/sheet.mjs +3 -3
- package/dist/components/ui/skeleton.js +33 -1
- package/dist/components/ui/skeleton.mjs +2 -2
- package/dist/components/ui/slider.js +86 -102
- package/dist/components/ui/slider.mjs +2 -2
- package/dist/components/ui/spinner.js +33 -1
- package/dist/components/ui/spinner.mjs +2 -2
- package/dist/components/ui/stage-timeline.js +579 -0
- package/dist/components/ui/stage-timeline.mjs +15 -0
- package/dist/components/ui/switch.js +37 -4
- package/dist/components/ui/switch.mjs +2 -3
- package/dist/components/ui/table.js +37 -5
- package/dist/components/ui/table.mjs +2 -2
- package/dist/components/ui/tabs.js +36 -12
- package/dist/components/ui/tabs.mjs +2 -2
- package/dist/components/ui/textarea.js +34 -2
- package/dist/components/ui/textarea.mjs +2 -2
- package/dist/components/ui/toggle-group.js +35 -4
- package/dist/components/ui/toggle-group.mjs +3 -4
- package/dist/components/ui/toggle.js +35 -4
- package/dist/components/ui/toggle.mjs +2 -3
- package/dist/components/ui/tooltip.js +51 -22
- package/dist/components/ui/tooltip.mjs +3 -3
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +528 -0
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +16 -0
- package/dist/components/ui/transactions-income-expense-bar-chart.js +516 -0
- package/dist/components/ui/transactions-income-expense-bar-chart.mjs +16 -0
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +528 -0
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +16 -0
- package/dist/index.js +11613 -2868
- package/dist/index.mjs +377 -164
- package/dist/lib/theme-provider.js +10 -1
- package/dist/lib/theme-provider.mjs +1 -1
- package/dist/lib/typography.js +8 -0
- package/dist/lib/typography.mjs +3 -1
- package/dist/lib/utils.js +33 -1
- package/dist/lib/utils.mjs +1 -1
- package/dist/styles.css +1 -1
- package/package.json +169 -6
- package/src/components/index.tsx +323 -13
- package/src/components/ui/accordion.tsx +6 -3
- package/src/components/ui/add-column-modal.tsx +339 -0
- package/src/components/ui/add-lead-modal.tsx +290 -0
- package/src/components/ui/ai-assistant-drawer.tsx +408 -0
- package/src/components/ui/alert-dialog.tsx +80 -54
- package/src/components/ui/alert.tsx +28 -28
- package/src/components/ui/avatar.tsx +30 -29
- package/src/components/ui/backoffice-alert-history-chart.tsx +260 -0
- package/src/components/ui/backoffice-contact-history-chart.tsx +325 -0
- package/src/components/ui/badge.tsx +17 -15
- package/src/components/ui/borrowing-capacity-line-chart.tsx +357 -0
- package/src/components/ui/button.tsx +30 -27
- package/src/components/ui/calendar.tsx +53 -67
- package/src/components/ui/card.tsx +27 -24
- package/src/components/ui/cash-balance-line-chart.tsx +302 -0
- package/src/components/ui/cashflow-bar-chart.tsx +363 -0
- package/src/components/ui/chart-shared.tsx +261 -0
- package/src/components/ui/checkbox.tsx +30 -26
- package/src/components/ui/combobox.tsx +223 -0
- package/src/components/ui/data-table.tsx +160 -99
- package/src/components/ui/date-picker.tsx +0 -2
- package/src/components/ui/dialog.tsx +70 -60
- package/src/components/ui/drawer.tsx +57 -48
- package/src/components/ui/dropdown-menu.tsx +90 -82
- package/src/components/ui/empty.tsx +31 -27
- package/src/components/ui/expense-bar-chart.tsx +296 -0
- package/src/components/ui/field.tsx +70 -62
- package/src/components/ui/financial-cards.tsx +830 -0
- package/src/components/ui/financial-drawers.tsx +339 -0
- package/src/components/ui/financial-primitives.tsx +331 -0
- package/src/components/ui/financial-sections.tsx +672 -0
- package/src/components/ui/form-primitives.tsx +536 -0
- package/src/components/ui/income-bar-chart.tsx +297 -0
- package/src/components/ui/input-group.tsx +41 -34
- package/src/components/ui/input-otp.tsx +29 -24
- package/src/components/ui/input.tsx +8 -8
- package/src/components/ui/kanban-column.tsx +333 -0
- package/src/components/ui/label.tsx +9 -12
- package/src/components/ui/opportunity-card.tsx +616 -0
- package/src/components/ui/opportunity-edit-modals.tsx +2528 -0
- package/src/components/ui/opportunity-summary-tab.tsx +579 -0
- package/src/components/ui/pipeline-alerts.tsx +74 -0
- package/src/components/ui/pipeline-board.tsx +268 -0
- package/src/components/ui/pipeline-chart.tsx +173 -0
- package/src/components/ui/pipeline-dialogs.tsx +303 -0
- package/src/components/ui/pipeline-primitives.tsx +108 -0
- package/src/components/ui/popover.tsx +41 -36
- package/src/components/ui/property-cashflow-doughnut-chart.tsx +188 -0
- package/src/components/ui/property-debt-equity-doughnut-chart.tsx +185 -0
- package/src/components/ui/property-mobile-estimate-line-chart.tsx +393 -0
- package/src/components/ui/select.tsx +65 -52
- package/src/components/ui/sheet.tsx +55 -52
- package/src/components/ui/slider.tsx +54 -77
- package/src/components/ui/stage-timeline.tsx +205 -0
- package/src/components/ui/switch.tsx +42 -29
- package/src/components/ui/table.tsx +28 -28
- package/src/components/ui/tabs.tsx +22 -28
- package/src/components/ui/textarea.tsx +8 -8
- package/src/components/ui/toggle-group.tsx +0 -2
- package/src/components/ui/toggle.tsx +13 -15
- package/src/components/ui/tooltip.tsx +30 -28
- package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +191 -0
- package/src/components/ui/transactions-income-expense-bar-chart.tsx +205 -0
- package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +191 -0
- package/src/lib/theme-provider.tsx +10 -0
- package/src/lib/typography.ts +9 -0
- package/src/lib/utils.ts +41 -3
- package/src/styles/globals.css +371 -124
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +32 -0
- package/dist/chunk-K74JRTJR.mjs +0 -105
- package/dist/chunk-V7CNWJT3.mjs +0 -10
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { addDays, startOfDay, format } from "date-fns";
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
import {
|
|
5
|
+
Dialog,
|
|
6
|
+
DialogContent,
|
|
7
|
+
DialogDescription,
|
|
8
|
+
DialogHeader,
|
|
9
|
+
DialogTitle,
|
|
10
|
+
DialogFooter,
|
|
11
|
+
} from "@/components/ui/dialog";
|
|
12
|
+
import { Button } from "@/components/ui/button";
|
|
13
|
+
import {
|
|
14
|
+
Select,
|
|
15
|
+
SelectContent,
|
|
16
|
+
SelectItem,
|
|
17
|
+
SelectTrigger,
|
|
18
|
+
SelectValue,
|
|
19
|
+
} from "@/components/ui/select";
|
|
20
|
+
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
|
21
|
+
import { DatePicker } from "@/components/ui/date-picker";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Pipeline Dialogs — WealthX DS (L4)
|
|
25
|
+
*
|
|
26
|
+
* Small, focused dialogs for Pipeline / Loan CRM actions:
|
|
27
|
+
* - DeleteOpportunityDialog — confirm card deletion
|
|
28
|
+
* - ChangePriorityDialog — select priority (Auto / Low / Medium / High)
|
|
29
|
+
* - PutOnHoldDialog — choose a hold-until date (preset or custom)
|
|
30
|
+
*
|
|
31
|
+
* All dialogs are fully controlled (`open` + `onOpenChange`).
|
|
32
|
+
* The `loading` prop disables actions and prevents accidental close.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// DeleteOpportunityDialog
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
export interface DeleteOpportunityDialogProps {
|
|
40
|
+
open: boolean;
|
|
41
|
+
/** Disables buttons and prevents close while an async op is in-flight. */
|
|
42
|
+
loading?: boolean;
|
|
43
|
+
onOpenChange: (open: boolean) => void;
|
|
44
|
+
onConfirm: () => void;
|
|
45
|
+
className?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function DeleteOpportunityDialog({
|
|
49
|
+
open,
|
|
50
|
+
loading = false,
|
|
51
|
+
onOpenChange,
|
|
52
|
+
onConfirm,
|
|
53
|
+
className,
|
|
54
|
+
}: DeleteOpportunityDialogProps) {
|
|
55
|
+
return (
|
|
56
|
+
<Dialog open={open} onOpenChange={loading ? undefined : onOpenChange}>
|
|
57
|
+
<DialogContent
|
|
58
|
+
showCloseButton={!loading}
|
|
59
|
+
className={cn("max-w-sm", className)}
|
|
60
|
+
>
|
|
61
|
+
<DialogHeader>
|
|
62
|
+
<DialogTitle>Want to delete this card?</DialogTitle>
|
|
63
|
+
<DialogDescription>
|
|
64
|
+
Doing so will also remove all associated loan applications and
|
|
65
|
+
tasks. This action cannot be undone.
|
|
66
|
+
</DialogDescription>
|
|
67
|
+
</DialogHeader>
|
|
68
|
+
<DialogFooter>
|
|
69
|
+
<Button
|
|
70
|
+
variant="outline"
|
|
71
|
+
onClick={() => onOpenChange(false)}
|
|
72
|
+
disabled={loading}
|
|
73
|
+
>
|
|
74
|
+
Cancel
|
|
75
|
+
</Button>
|
|
76
|
+
<Button variant="destructive" onClick={onConfirm} disabled={loading}>
|
|
77
|
+
{loading ? "Deleting…" : "Delete"}
|
|
78
|
+
</Button>
|
|
79
|
+
</DialogFooter>
|
|
80
|
+
</DialogContent>
|
|
81
|
+
</Dialog>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// ChangePriorityDialog
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
export type PrioritySelection = "auto" | "low" | "medium" | "high";
|
|
90
|
+
|
|
91
|
+
const PRIORITY_OPTIONS: {
|
|
92
|
+
value: PrioritySelection;
|
|
93
|
+
label: string;
|
|
94
|
+
color: string;
|
|
95
|
+
}[] = [
|
|
96
|
+
{ value: "auto", label: "Auto", color: "var(--color-muted-foreground)" },
|
|
97
|
+
{ value: "low", label: "Low", color: "var(--color-success)" },
|
|
98
|
+
{ value: "medium", label: "Medium", color: "var(--color-warning)" },
|
|
99
|
+
{ value: "high", label: "High", color: "var(--color-destructive)" },
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
export interface ChangePriorityDialogProps {
|
|
103
|
+
open: boolean;
|
|
104
|
+
value: PrioritySelection;
|
|
105
|
+
loading?: boolean;
|
|
106
|
+
onOpenChange: (open: boolean) => void;
|
|
107
|
+
onSave: () => void;
|
|
108
|
+
onSelectionChange: (value: PrioritySelection) => void;
|
|
109
|
+
className?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function ChangePriorityDialog({
|
|
113
|
+
open,
|
|
114
|
+
value,
|
|
115
|
+
loading = false,
|
|
116
|
+
onOpenChange,
|
|
117
|
+
onSave,
|
|
118
|
+
onSelectionChange,
|
|
119
|
+
className,
|
|
120
|
+
}: ChangePriorityDialogProps) {
|
|
121
|
+
return (
|
|
122
|
+
<Dialog open={open} onOpenChange={loading ? undefined : onOpenChange}>
|
|
123
|
+
<DialogContent className={cn("max-w-sm", className)}>
|
|
124
|
+
<DialogHeader>
|
|
125
|
+
<DialogTitle>Change priority</DialogTitle>
|
|
126
|
+
</DialogHeader>
|
|
127
|
+
<Select
|
|
128
|
+
value={value}
|
|
129
|
+
onValueChange={(v) => onSelectionChange(v as PrioritySelection)}
|
|
130
|
+
>
|
|
131
|
+
<SelectTrigger className="w-full">
|
|
132
|
+
{(() => {
|
|
133
|
+
const opt = PRIORITY_OPTIONS.find((o) => o.value === value);
|
|
134
|
+
return opt ? (
|
|
135
|
+
<span className="flex items-center gap-2">
|
|
136
|
+
<span
|
|
137
|
+
className="inline-block size-2 shrink-0 rounded-full"
|
|
138
|
+
style={{ backgroundColor: opt.color }}
|
|
139
|
+
aria-hidden="true"
|
|
140
|
+
/>
|
|
141
|
+
{opt.label}
|
|
142
|
+
</span>
|
|
143
|
+
) : null;
|
|
144
|
+
})()}
|
|
145
|
+
</SelectTrigger>
|
|
146
|
+
<SelectContent>
|
|
147
|
+
{PRIORITY_OPTIONS.map((opt) => (
|
|
148
|
+
<SelectItem key={opt.value} value={opt.value}>
|
|
149
|
+
<span className="flex items-center gap-2">
|
|
150
|
+
<span
|
|
151
|
+
className="inline-block size-2 shrink-0 rounded-full"
|
|
152
|
+
style={{ backgroundColor: opt.color }}
|
|
153
|
+
aria-hidden="true"
|
|
154
|
+
/>
|
|
155
|
+
{opt.label}
|
|
156
|
+
</span>
|
|
157
|
+
</SelectItem>
|
|
158
|
+
))}
|
|
159
|
+
</SelectContent>
|
|
160
|
+
</Select>
|
|
161
|
+
<DialogFooter>
|
|
162
|
+
<Button
|
|
163
|
+
variant="outline"
|
|
164
|
+
onClick={() => onOpenChange(false)}
|
|
165
|
+
disabled={loading}
|
|
166
|
+
>
|
|
167
|
+
Cancel
|
|
168
|
+
</Button>
|
|
169
|
+
<Button onClick={onSave} disabled={loading}>
|
|
170
|
+
{loading ? "Saving…" : "Save"}
|
|
171
|
+
</Button>
|
|
172
|
+
</DialogFooter>
|
|
173
|
+
</DialogContent>
|
|
174
|
+
</Dialog>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
// PutOnHoldDialog
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
|
|
182
|
+
export type HoldDuration = "90" | "180" | "360" | "custom";
|
|
183
|
+
|
|
184
|
+
const HOLD_OPTIONS: { value: HoldDuration; label: string }[] = [
|
|
185
|
+
{ value: "90", label: "90 Days" },
|
|
186
|
+
{ value: "180", label: "180 Days" },
|
|
187
|
+
{ value: "360", label: "360 Days" },
|
|
188
|
+
{ value: "custom", label: "Custom" },
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
export interface PutOnHoldDialogProps {
|
|
192
|
+
open: boolean;
|
|
193
|
+
loading?: boolean;
|
|
194
|
+
onOpenChange: (open: boolean) => void;
|
|
195
|
+
/** Called with an ISO date string (yyyy-MM-dd) when the user saves. */
|
|
196
|
+
onSave: (isoDate: string) => void;
|
|
197
|
+
className?: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function PutOnHoldDialog({
|
|
201
|
+
open,
|
|
202
|
+
loading = false,
|
|
203
|
+
onOpenChange,
|
|
204
|
+
onSave,
|
|
205
|
+
className,
|
|
206
|
+
}: PutOnHoldDialogProps) {
|
|
207
|
+
const [duration, setDuration] = React.useState<HoldDuration>("90");
|
|
208
|
+
const [customDate, setCustomDate] = React.useState<Date | undefined>();
|
|
209
|
+
const today = React.useMemo(() => startOfDay(new Date()), []);
|
|
210
|
+
|
|
211
|
+
const resolvedDate = React.useMemo<Date | undefined>(() => {
|
|
212
|
+
if (duration === "custom") return customDate;
|
|
213
|
+
return addDays(today, parseInt(duration, 10));
|
|
214
|
+
}, [duration, customDate, today]);
|
|
215
|
+
|
|
216
|
+
const isValid = resolvedDate !== undefined && resolvedDate >= today;
|
|
217
|
+
|
|
218
|
+
function handleSave() {
|
|
219
|
+
if (!resolvedDate) return;
|
|
220
|
+
onSave(format(resolvedDate, "yyyy-MM-dd"));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Reset when dialog opens
|
|
224
|
+
React.useEffect(() => {
|
|
225
|
+
if (open) {
|
|
226
|
+
setDuration("90");
|
|
227
|
+
setCustomDate(undefined);
|
|
228
|
+
}
|
|
229
|
+
}, [open]);
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
<Dialog open={open} onOpenChange={loading ? undefined : onOpenChange}>
|
|
233
|
+
<DialogContent className={cn("max-w-sm", className)}>
|
|
234
|
+
<DialogHeader>
|
|
235
|
+
<DialogTitle>Hold and Hide Until Later Date</DialogTitle>
|
|
236
|
+
</DialogHeader>
|
|
237
|
+
<div className="flex flex-col gap-4">
|
|
238
|
+
<ToggleGroup
|
|
239
|
+
type="single"
|
|
240
|
+
variant="outline"
|
|
241
|
+
size="sm"
|
|
242
|
+
value={[duration]}
|
|
243
|
+
onValueChange={(v) => {
|
|
244
|
+
if (v.length) setDuration(v[0] as HoldDuration);
|
|
245
|
+
}}
|
|
246
|
+
className="w-full"
|
|
247
|
+
>
|
|
248
|
+
{HOLD_OPTIONS.map((opt) => (
|
|
249
|
+
<ToggleGroupItem
|
|
250
|
+
key={opt.value}
|
|
251
|
+
value={opt.value}
|
|
252
|
+
className="flex-1"
|
|
253
|
+
>
|
|
254
|
+
{opt.label}
|
|
255
|
+
</ToggleGroupItem>
|
|
256
|
+
))}
|
|
257
|
+
</ToggleGroup>
|
|
258
|
+
|
|
259
|
+
{/* Fixed-height row — same h-9 in all tab states to prevent layout jump */}
|
|
260
|
+
{duration === "custom" ? (
|
|
261
|
+
<DatePicker
|
|
262
|
+
value={customDate}
|
|
263
|
+
onChange={setCustomDate}
|
|
264
|
+
placeholder="Pick a date"
|
|
265
|
+
calendarProps={{ disabled: { before: today } }}
|
|
266
|
+
/>
|
|
267
|
+
) : (
|
|
268
|
+
resolvedDate && (
|
|
269
|
+
<div className="flex h-9 items-center border border-input bg-muted/30 px-3 text-sm text-muted-foreground">
|
|
270
|
+
Hold until:{" "}
|
|
271
|
+
<span className="ml-1 font-medium text-foreground">
|
|
272
|
+
{format(resolvedDate, "dd MMM yyyy")}
|
|
273
|
+
</span>
|
|
274
|
+
</div>
|
|
275
|
+
)
|
|
276
|
+
)}
|
|
277
|
+
|
|
278
|
+
{/* For custom: show resolved date below the picker once selected */}
|
|
279
|
+
{duration === "custom" && customDate && (
|
|
280
|
+
<p className="text-sm text-muted-foreground">
|
|
281
|
+
Hold until:{" "}
|
|
282
|
+
<span className="font-medium text-foreground">
|
|
283
|
+
{format(customDate, "dd MMM yyyy")}
|
|
284
|
+
</span>
|
|
285
|
+
</p>
|
|
286
|
+
)}
|
|
287
|
+
</div>
|
|
288
|
+
<DialogFooter>
|
|
289
|
+
<Button
|
|
290
|
+
variant="outline"
|
|
291
|
+
onClick={() => onOpenChange(false)}
|
|
292
|
+
disabled={loading}
|
|
293
|
+
>
|
|
294
|
+
Cancel
|
|
295
|
+
</Button>
|
|
296
|
+
<Button onClick={handleSave} disabled={loading || !isValid}>
|
|
297
|
+
{loading ? "Saving…" : "Save"}
|
|
298
|
+
</Button>
|
|
299
|
+
</DialogFooter>
|
|
300
|
+
</DialogContent>
|
|
301
|
+
</Dialog>
|
|
302
|
+
);
|
|
303
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
import { Badge } from "@/components/ui/badge";
|
|
3
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Pipeline domain primitives — WealthX DS
|
|
7
|
+
*
|
|
8
|
+
* Complex domain-specific atoms for the Pipeline / Loan CRM feature
|
|
9
|
+
* that cannot be expressed as simple use-cases of existing primitives.
|
|
10
|
+
*
|
|
11
|
+
* Simple patterns (priority dot, days chip, loan type badge, progress bar)
|
|
12
|
+
* are documented as use-cases in their respective base component stories
|
|
13
|
+
* (Badge, Chip, Progress) — not exported as separate components.
|
|
14
|
+
*
|
|
15
|
+
* Layer: L2 Domain Primitive
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// TaskCheckItem
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
export interface TaskCheckItemProps {
|
|
23
|
+
/** Task display title. */
|
|
24
|
+
title: string;
|
|
25
|
+
/** Whether the task has been completed. */
|
|
26
|
+
completed: boolean;
|
|
27
|
+
/** Name of the AI agent assigned to this task, if any. */
|
|
28
|
+
aiAgentName?: string | null;
|
|
29
|
+
/** Called when the checkbox is toggled. */
|
|
30
|
+
onToggle?: () => void;
|
|
31
|
+
/** Disables interaction (e.g. while saving). */
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Text size for the task title.
|
|
35
|
+
* - "xs" (default) — 12px, for compact card usage
|
|
36
|
+
* - "sm" — 14px, for standalone / drawer usage
|
|
37
|
+
*/
|
|
38
|
+
size?: "xs" | "sm";
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A single task row with a checkbox, title (strikethrough when done),
|
|
44
|
+
* and an optional AI agent chip.
|
|
45
|
+
*
|
|
46
|
+
* Used in two contexts:
|
|
47
|
+
* - `OpportunityCard` (kanban card) — default `size="xs"` (12px), compact
|
|
48
|
+
* - `StageTimeline` (drawer Tasks tab) — `size="sm"` (14px), standalone
|
|
49
|
+
*
|
|
50
|
+
* Data source: `Opportunity.tasks[]` from `loan-crm.ts`
|
|
51
|
+
* - `completed` ← `task.completedTaskId !== null`
|
|
52
|
+
* - `aiAgentName` ← `task.aiAgentName`
|
|
53
|
+
*/
|
|
54
|
+
export function TaskCheckItem({
|
|
55
|
+
title,
|
|
56
|
+
completed,
|
|
57
|
+
aiAgentName,
|
|
58
|
+
onToggle,
|
|
59
|
+
disabled = false,
|
|
60
|
+
size = "xs",
|
|
61
|
+
className,
|
|
62
|
+
}: TaskCheckItemProps) {
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
className={cn(
|
|
66
|
+
"flex cursor-pointer items-start gap-2 py-1.5",
|
|
67
|
+
disabled && "pointer-events-none opacity-60",
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
onClick={() => onToggle?.()}
|
|
71
|
+
data-slot="task-check-item"
|
|
72
|
+
>
|
|
73
|
+
{/*
|
|
74
|
+
* Wrapper span stops click propagation so the outer div's onClick doesn't
|
|
75
|
+
* double-fire when the user clicks the Checkbox button directly.
|
|
76
|
+
* (Radix Checkbox renders as <button> — clicking it fires onCheckedChange,
|
|
77
|
+
* then the event would bubble to the div and call onToggle a second time.)
|
|
78
|
+
*/}
|
|
79
|
+
<span onClick={(e) => e.stopPropagation()} className="mt-0.5 shrink-0">
|
|
80
|
+
<Checkbox
|
|
81
|
+
checked={completed}
|
|
82
|
+
onCheckedChange={() => onToggle?.()}
|
|
83
|
+
disabled={disabled}
|
|
84
|
+
/>
|
|
85
|
+
</span>
|
|
86
|
+
<span className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
87
|
+
<span
|
|
88
|
+
className={cn(
|
|
89
|
+
"leading-snug text-foreground",
|
|
90
|
+
size === "sm" ? "text-sm" : "text-xs",
|
|
91
|
+
completed && "text-muted-foreground line-through",
|
|
92
|
+
)}
|
|
93
|
+
>
|
|
94
|
+
{title}
|
|
95
|
+
</span>
|
|
96
|
+
{aiAgentName && (
|
|
97
|
+
<Badge variant="secondary" className="gap-1 text-[10px]">
|
|
98
|
+
<span
|
|
99
|
+
className="size-1.5 rounded-full bg-primary"
|
|
100
|
+
aria-hidden="true"
|
|
101
|
+
/>
|
|
102
|
+
{aiAgentName}
|
|
103
|
+
</Badge>
|
|
104
|
+
)}
|
|
105
|
+
</span>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { type ReactElement } from "react"
|
|
2
|
-
import * as React from "react"
|
|
3
|
-
import { Popover as PopoverPrimitive } from "@base-ui/react/popover"
|
|
4
|
-
import { cn } from "@/lib/utils"
|
|
5
|
-
import { useThemeVars } from "@/lib/theme-provider"
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
import { useThemeVars } from "@/lib/theme-provider";
|
|
6
6
|
|
|
7
|
-
export type PopoverProps = React.ComponentProps<typeof PopoverPrimitive.Root
|
|
7
|
+
export type PopoverProps = React.ComponentProps<typeof PopoverPrimitive.Root>;
|
|
8
8
|
|
|
9
|
-
function Popover({
|
|
10
|
-
...props
|
|
11
|
-
}: PopoverProps): ReactElement {
|
|
12
|
-
return <PopoverPrimitive.Root data-slot="popover" {...props} />
|
|
9
|
+
function Popover({ ...props }: PopoverProps): ReactElement {
|
|
10
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
export type PopoverTriggerProps = React.ComponentProps<
|
|
13
|
+
export type PopoverTriggerProps = React.ComponentProps<
|
|
14
|
+
typeof PopoverPrimitive.Trigger
|
|
15
|
+
>;
|
|
16
16
|
|
|
17
|
-
function PopoverTrigger({
|
|
18
|
-
...props
|
|
19
|
-
}: PopoverTriggerProps): ReactElement {
|
|
20
|
-
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
|
|
17
|
+
function PopoverTrigger({ ...props }: PopoverTriggerProps): ReactElement {
|
|
18
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
export type PopoverContentProps = React.ComponentProps<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
export type PopoverContentProps = React.ComponentProps<
|
|
22
|
+
typeof PopoverPrimitive.Popup
|
|
23
|
+
> & {
|
|
24
|
+
align?: "start" | "center" | "end";
|
|
25
|
+
sideOffset?: number;
|
|
26
|
+
};
|
|
27
27
|
|
|
28
28
|
function PopoverContent({
|
|
29
29
|
className,
|
|
@@ -36,13 +36,14 @@ function PopoverContent({
|
|
|
36
36
|
return (
|
|
37
37
|
<PopoverPrimitive.Portal>
|
|
38
38
|
<PopoverPrimitive.Positioner
|
|
39
|
+
className="z-[200]"
|
|
39
40
|
align={align}
|
|
40
41
|
sideOffset={sideOffset}
|
|
41
42
|
>
|
|
42
43
|
<PopoverPrimitive.Popup
|
|
43
44
|
className={cn(
|
|
44
45
|
"z-50 w-72 border border-border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:zoom-out-95 data-ending-style:fill-mode-forwards data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95",
|
|
45
|
-
className
|
|
46
|
+
className,
|
|
46
47
|
)}
|
|
47
48
|
data-slot="popover-content"
|
|
48
49
|
style={{ ...themeVars, ...style } as React.CSSProperties}
|
|
@@ -50,32 +51,36 @@ function PopoverContent({
|
|
|
50
51
|
/>
|
|
51
52
|
</PopoverPrimitive.Positioner>
|
|
52
53
|
</PopoverPrimitive.Portal>
|
|
53
|
-
)
|
|
54
|
+
);
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
export type PopoverAnchorProps = React.ComponentProps<"div"
|
|
57
|
+
export type PopoverAnchorProps = React.ComponentProps<"div">;
|
|
57
58
|
|
|
58
|
-
function PopoverAnchor({
|
|
59
|
-
...props
|
|
60
|
-
}: PopoverAnchorProps): ReactElement {
|
|
61
|
-
return <div data-slot="popover-anchor" {...props} />
|
|
59
|
+
function PopoverAnchor({ ...props }: PopoverAnchorProps): ReactElement {
|
|
60
|
+
return <div data-slot="popover-anchor" {...props} />;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
export type PopoverHeaderProps = React.ComponentProps<"div"
|
|
63
|
+
export type PopoverHeaderProps = React.ComponentProps<"div">;
|
|
65
64
|
|
|
66
|
-
function PopoverHeader({
|
|
65
|
+
function PopoverHeader({
|
|
66
|
+
className,
|
|
67
|
+
...props
|
|
68
|
+
}: PopoverHeaderProps): ReactElement {
|
|
67
69
|
return (
|
|
68
70
|
<div
|
|
69
|
-
className={cn("flex flex-col gap-1 text-
|
|
71
|
+
className={cn("flex flex-col gap-1 text-body-small", className)}
|
|
70
72
|
data-slot="popover-header"
|
|
71
73
|
{...props}
|
|
72
74
|
/>
|
|
73
|
-
)
|
|
75
|
+
);
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
export type PopoverTitleProps = React.ComponentProps<"h2"
|
|
78
|
+
export type PopoverTitleProps = React.ComponentProps<"h2">;
|
|
77
79
|
|
|
78
|
-
function PopoverTitle({
|
|
80
|
+
function PopoverTitle({
|
|
81
|
+
className,
|
|
82
|
+
...props
|
|
83
|
+
}: PopoverTitleProps): ReactElement {
|
|
79
84
|
return (
|
|
80
85
|
// eslint-disable-next-line jsx-a11y/heading-has-content -- children passed via props spread
|
|
81
86
|
<h2
|
|
@@ -83,10 +88,10 @@ function PopoverTitle({ className, ...props }: PopoverTitleProps): ReactElement
|
|
|
83
88
|
data-slot="popover-title"
|
|
84
89
|
{...props}
|
|
85
90
|
/>
|
|
86
|
-
)
|
|
91
|
+
);
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
export type PopoverDescriptionProps = React.ComponentProps<"p"
|
|
94
|
+
export type PopoverDescriptionProps = React.ComponentProps<"p">;
|
|
90
95
|
|
|
91
96
|
function PopoverDescription({
|
|
92
97
|
className,
|
|
@@ -98,7 +103,7 @@ function PopoverDescription({
|
|
|
98
103
|
data-slot="popover-description"
|
|
99
104
|
{...props}
|
|
100
105
|
/>
|
|
101
|
-
)
|
|
106
|
+
);
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
export {
|
|
@@ -109,4 +114,4 @@ export {
|
|
|
109
114
|
PopoverHeader,
|
|
110
115
|
PopoverTitle,
|
|
111
116
|
PopoverDescription,
|
|
112
|
-
}
|
|
117
|
+
};
|