@wealthx/shadcn 1.2.2 → 1.3.1
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 +193 -149
- package/CHANGELOG.md +28 -0
- package/dist/{chunk-4Y6R4WEC.mjs → chunk-2A5RRQGG.mjs} +9 -22
- package/dist/{chunk-TS2ZX2VS.mjs → chunk-2UM72RJ7.mjs} +11 -15
- package/dist/{chunk-A56YQQHG.mjs → chunk-3NCUZIFP.mjs} +2 -2
- package/dist/chunk-3OYFOX3X.mjs +79 -0
- package/dist/{chunk-RP3SQYA3.mjs → chunk-3TTACBDP.mjs} +9 -4
- package/dist/chunk-4GAWMKMI.mjs +710 -0
- package/dist/{chunk-VGSESELX.mjs → chunk-5FQIKDKP.mjs} +5 -5
- package/dist/{chunk-K3JYD4IU.mjs → chunk-5IS7G74I.mjs} +11 -4
- package/dist/chunk-6AW4KJHE.mjs +235 -0
- package/dist/chunk-6CR5N2JW.mjs +302 -0
- package/dist/{chunk-XIRTEFKH.mjs → chunk-6DZEXFNB.mjs} +36 -8
- package/dist/chunk-6O6KD7CE.mjs +271 -0
- package/dist/chunk-7PV3IWCN.mjs +33 -0
- package/dist/{chunk-SPJ5KXW7.mjs → chunk-7S5AESZO.mjs} +5 -5
- package/dist/{chunk-RYCLWMZ7.mjs → chunk-ABFDMHOR.mjs} +9 -7
- package/dist/{chunk-SWGT756Z.mjs → chunk-AMQZRHEZ.mjs} +10 -4
- package/dist/{chunk-WAZD7NFU.mjs → chunk-BKNFWEH2.mjs} +6 -6
- package/dist/{chunk-CLIN5525.mjs → chunk-C7CQJNMR.mjs} +1 -1
- package/dist/{chunk-D4ILTPOG.mjs → chunk-CFMQP5QS.mjs} +5 -4
- package/dist/{chunk-VPBN3WOO.mjs → chunk-DGHAXJBN.mjs} +9 -7
- package/dist/chunk-DOEO3CDL.mjs +27 -0
- package/dist/{chunk-5MEWU56Z.mjs → chunk-DUJTAXMH.mjs} +11 -6
- package/dist/{chunk-GGM2UYGG.mjs → chunk-EBXQWIYG.mjs} +10 -4
- package/dist/chunk-EWRB4PAD.mjs +468 -0
- package/dist/{chunk-ZSHYDDRB.mjs → chunk-FAKPBKLT.mjs} +6 -2
- package/dist/{chunk-A6AAWBPF.mjs → chunk-GHC7LLUX.mjs} +13 -4
- package/dist/chunk-HBZLGDIN.mjs +507 -0
- package/dist/{chunk-SIZMLSRU.mjs → chunk-HISNT2MG.mjs} +8 -6
- package/dist/{chunk-CGH4DRNG.mjs → chunk-HVY6KCCF.mjs} +10 -7
- package/dist/chunk-I3RZS7V2.mjs +136 -0
- package/dist/chunk-IAE3F7DR.mjs +1962 -0
- package/dist/{chunk-UT4KJR7V.mjs → chunk-IHMFS7NZ.mjs} +35 -74
- package/dist/{chunk-PCPLO5HT.mjs → chunk-IOJRDS6V.mjs} +96 -14
- package/dist/{chunk-LHYCMLVA.mjs → chunk-JKGDCQTZ.mjs} +11 -4
- package/dist/{chunk-H45TKD34.mjs → chunk-JMHR3YGZ.mjs} +1 -1
- package/dist/{chunk-4MN6UQHG.mjs → chunk-K5A5L6T2.mjs} +17 -39
- package/dist/chunk-LV35NGVG.mjs +272 -0
- package/dist/{chunk-FZIXGLMV.mjs → chunk-M3FV7LOK.mjs} +5 -12
- package/dist/{chunk-FMAXJ2SI.mjs → chunk-MBON7YRJ.mjs} +1 -1
- package/dist/chunk-MIZQHHUO.mjs +441 -0
- package/dist/chunk-MLNEWRWV.mjs +449 -0
- package/dist/chunk-MN5NYQCL.mjs +29 -0
- package/dist/chunk-NL3ZO62D.mjs +31 -0
- package/dist/{chunk-Q76O3RIQ.mjs → chunk-NMOI6CQD.mjs} +1 -1
- package/dist/{chunk-P6AM5V7O.mjs → chunk-OODBHKG7.mjs} +1 -1
- package/dist/chunk-PBL4OQV2.mjs +283 -0
- package/dist/{chunk-Y4QFWRNR.mjs → chunk-PU4YZQXV.mjs} +17 -18
- package/dist/chunk-Q2BGOAMG.mjs +202 -0
- package/dist/chunk-QMY3AZJH.mjs +80 -0
- package/dist/{chunk-BL3DXM2X.mjs → chunk-QZ4RE6NA.mjs} +11 -4
- package/dist/{chunk-VACKZOMY.mjs → chunk-R3VSPKNP.mjs} +3 -3
- package/dist/{chunk-OPNQAVVH.mjs → chunk-RJI6GKVF.mjs} +8 -6
- package/dist/{chunk-WG6JGJXB.mjs → chunk-T4BJLT57.mjs} +1 -1
- package/dist/chunk-UMTOX62O.mjs +415 -0
- package/dist/{chunk-7MMXNK3C.mjs → chunk-VLARHE5V.mjs} +8 -6
- package/dist/{chunk-2I5S2AMY.mjs → chunk-XREGSKX3.mjs} +2 -2
- package/dist/{chunk-JNQORUPP.mjs → chunk-YJG55G2H.mjs} +14 -11
- package/dist/components/ui/add-column-modal.js +42 -14
- package/dist/components/ui/add-column-modal.mjs +5 -5
- package/dist/components/ui/add-lead-modal.js +42 -11
- package/dist/components/ui/add-lead-modal.mjs +3 -3
- package/dist/components/ui/advisor-card.js +530 -0
- package/dist/components/ui/advisor-card.mjs +15 -0
- package/dist/components/ui/ai-assistant-drawer.js +11 -10
- package/dist/components/ui/ai-assistant-drawer.mjs +3 -3
- package/dist/components/ui/alert-dialog.js +2 -2
- package/dist/components/ui/alert-dialog.mjs +2 -2
- package/dist/components/ui/appointment-action-dialogs.js +1160 -0
- package/dist/components/ui/appointment-action-dialogs.mjs +23 -0
- package/dist/components/ui/appointment-availability-settings.js +1590 -0
- package/dist/components/ui/appointment-availability-settings.mjs +23 -0
- package/dist/components/ui/appointment-book-dialog.js +1744 -0
- package/dist/components/ui/appointment-book-dialog.mjs +27 -0
- package/dist/components/ui/appointment-calendar-view.js +833 -0
- package/dist/components/ui/appointment-calendar-view.mjs +14 -0
- package/dist/components/ui/appointment-detail-sheet.js +1517 -0
- package/dist/components/ui/appointment-detail-sheet.mjs +24 -0
- package/dist/components/ui/appointment-gmail-connect.js +467 -0
- package/dist/components/ui/appointment-gmail-connect.mjs +14 -0
- package/dist/components/ui/appointment-mini-card.js +345 -0
- package/dist/components/ui/appointment-mini-card.mjs +11 -0
- package/dist/components/ui/appointment-time-slot-picker.js +311 -0
- package/dist/components/ui/appointment-time-slot-picker.mjs +13 -0
- package/dist/components/ui/appointment-upcoming-card.js +1268 -0
- package/dist/components/ui/appointment-upcoming-card.mjs +21 -0
- package/dist/components/ui/backoffice-alert-history-chart.js +11 -5
- package/dist/components/ui/backoffice-alert-history-chart.mjs +5 -4
- package/dist/components/ui/backoffice-alerts-chart.js +786 -0
- package/dist/components/ui/backoffice-alerts-chart.mjs +19 -0
- package/dist/components/ui/backoffice-connections-chart.js +817 -0
- package/dist/components/ui/backoffice-connections-chart.mjs +19 -0
- package/dist/components/ui/backoffice-contact-history-chart.js +11 -5
- package/dist/components/ui/backoffice-contact-history-chart.mjs +5 -4
- package/dist/components/ui/badge.js +6 -6
- package/dist/components/ui/badge.mjs +1 -1
- package/dist/components/ui/borrowing-capacity-line-chart.js +30 -21
- package/dist/components/ui/borrowing-capacity-line-chart.mjs +5 -4
- package/dist/components/ui/button.js +2 -2
- package/dist/components/ui/button.mjs +1 -1
- package/dist/components/ui/calendar.js +2 -2
- package/dist/components/ui/calendar.mjs +2 -2
- package/dist/components/ui/card.js +1 -1
- package/dist/components/ui/card.mjs +1 -1
- package/dist/components/ui/cash-balance-line-chart.js +31 -23
- package/dist/components/ui/cash-balance-line-chart.mjs +5 -4
- package/dist/components/ui/cashflow-bar-chart.js +12 -5
- package/dist/components/ui/cashflow-bar-chart.mjs +5 -4
- package/dist/components/ui/chip.js +97 -18
- package/dist/components/ui/chip.mjs +3 -2
- package/dist/components/ui/color-picker.js +158 -28
- package/dist/components/ui/color-picker.mjs +3 -1
- package/dist/components/ui/data-table.js +140 -119
- package/dist/components/ui/data-table.mjs +3 -2
- package/dist/components/ui/date-picker.js +48 -27
- package/dist/components/ui/date-picker.mjs +4 -3
- package/dist/components/ui/dialog.js +37 -9
- package/dist/components/ui/dialog.mjs +2 -2
- package/dist/components/ui/expense-bar-chart.js +12 -5
- package/dist/components/ui/expense-bar-chart.mjs +5 -4
- package/dist/components/ui/field.mjs +2 -2
- package/dist/components/ui/financial-cards.js +322 -155
- package/dist/components/ui/financial-cards.mjs +5 -3
- package/dist/components/ui/financial-drawers.js +2 -2
- package/dist/components/ui/financial-drawers.mjs +3 -3
- package/dist/components/ui/financial-sections.js +14 -10
- package/dist/components/ui/financial-sections.mjs +6 -5
- package/dist/components/ui/income-bar-chart.js +12 -5
- package/dist/components/ui/income-bar-chart.mjs +5 -4
- package/dist/components/ui/input-group.js +2 -2
- package/dist/components/ui/input-group.mjs +2 -2
- package/dist/components/ui/kanban-column.js +52 -44
- package/dist/components/ui/kanban-column.mjs +7 -5
- package/dist/components/ui/opportunity-card.js +52 -44
- package/dist/components/ui/opportunity-card.mjs +6 -4
- package/dist/components/ui/opportunity-edit-modals.js +1367 -1263
- package/dist/components/ui/opportunity-edit-modals.mjs +8 -8
- package/dist/components/ui/opportunity-summary-tab.js +2744 -2157
- package/dist/components/ui/opportunity-summary-tab.mjs +14 -14
- package/dist/components/ui/page-header.js +92 -0
- package/dist/components/ui/page-header.mjs +8 -0
- package/dist/components/ui/page-top-bar.js +88 -0
- package/dist/components/ui/page-top-bar.mjs +8 -0
- package/dist/components/ui/pagination.js +303 -19
- package/dist/components/ui/pagination.mjs +11 -4
- package/dist/components/ui/pipeline-board.js +205 -191
- package/dist/components/ui/pipeline-board.mjs +9 -7
- package/dist/components/ui/pipeline-dialogs.js +114 -65
- package/dist/components/ui/pipeline-dialogs.mjs +7 -6
- package/dist/components/ui/pipeline-primitives.js +6 -6
- package/dist/components/ui/pipeline-primitives.mjs +2 -2
- package/dist/components/ui/property-cashflow-doughnut-chart.js +14 -12
- package/dist/components/ui/property-cashflow-doughnut-chart.mjs +5 -4
- package/dist/components/ui/property-debt-equity-doughnut-chart.js +14 -12
- package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +5 -4
- package/dist/components/ui/property-mobile-estimate-line-chart.js +16 -14
- package/dist/components/ui/property-mobile-estimate-line-chart.mjs +5 -4
- package/dist/components/ui/sidebar-nav.js +426 -191
- package/dist/components/ui/sidebar-nav.mjs +5 -1
- package/dist/components/ui/stage-timeline.js +6 -6
- package/dist/components/ui/stage-timeline.mjs +3 -3
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +18 -16
- package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +5 -4
- package/dist/components/ui/transactions-income-expense-bar-chart.js +28 -12
- package/dist/components/ui/transactions-income-expense-bar-chart.mjs +5 -4
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +18 -16
- package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +5 -4
- package/dist/index.js +12258 -8611
- package/dist/index.mjs +258 -190
- package/dist/styles.css +1 -1
- package/package.json +71 -1
- package/src/components/index.tsx +115 -9
- package/src/components/ui/add-column-modal.tsx +7 -7
- package/src/components/ui/add-lead-modal.tsx +6 -3
- package/src/components/ui/advisor-card.tsx +284 -0
- package/src/components/ui/ai-assistant-drawer.tsx +4 -3
- package/src/components/ui/appointment-action-dialogs.tsx +297 -0
- package/src/components/ui/appointment-availability-settings.tsx +645 -0
- package/src/components/ui/appointment-book-dialog.tsx +618 -0
- package/src/components/ui/appointment-calendar-view.tsx +510 -0
- package/src/components/ui/appointment-detail-sheet.tsx +415 -0
- package/src/components/ui/appointment-gmail-connect.tsx +188 -0
- package/src/components/ui/appointment-mini-card.tsx +104 -0
- package/src/components/ui/appointment-time-slot-picker.tsx +123 -0
- package/src/components/ui/appointment-upcoming-card.tsx +635 -0
- package/src/components/ui/backoffice-alert-history-chart.tsx +10 -2
- package/src/components/ui/backoffice-alerts-chart.tsx +312 -0
- package/src/components/ui/backoffice-connections-chart.tsx +339 -0
- package/src/components/ui/backoffice-contact-history-chart.tsx +10 -2
- package/src/components/ui/badge.tsx +12 -6
- package/src/components/ui/borrowing-capacity-line-chart.tsx +4 -11
- package/src/components/ui/button.tsx +2 -2
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/cash-balance-line-chart.tsx +4 -23
- package/src/components/ui/cashflow-bar-chart.tsx +9 -2
- package/src/components/ui/chart-shared.tsx +4 -11
- package/src/components/ui/chip.tsx +23 -19
- package/src/components/ui/color-picker.tsx +4 -2
- package/src/components/ui/data-table.tsx +28 -74
- package/src/components/ui/date-picker.tsx +42 -37
- package/src/components/ui/dialog.tsx +72 -6
- package/src/components/ui/expense-bar-chart.tsx +11 -2
- package/src/components/ui/financial-cards.tsx +99 -10
- package/src/components/ui/income-bar-chart.tsx +11 -2
- package/src/components/ui/opportunity-card.tsx +10 -39
- package/src/components/ui/opportunity-edit-modals.tsx +98 -36
- package/src/components/ui/opportunity-summary-tab.tsx +548 -232
- package/src/components/ui/page-header.tsx +57 -0
- package/src/components/ui/page-top-bar.tsx +48 -0
- package/src/components/ui/pagination.tsx +171 -22
- package/src/components/ui/pipeline-board.tsx +12 -5
- package/src/components/ui/property-cashflow-doughnut-chart.tsx +3 -1
- package/src/components/ui/property-debt-equity-doughnut-chart.tsx +3 -1
- package/src/components/ui/property-mobile-estimate-line-chart.tsx +3 -1
- package/src/components/ui/sidebar-nav.tsx +213 -157
- package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +3 -1
- package/src/components/ui/transactions-income-expense-bar-chart.tsx +12 -9
- package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +3 -1
- package/src/lib/format-currency.ts +44 -0
- package/src/lib/format-date.ts +50 -0
- package/src/lib/opportunity-constants.ts +12 -0
- package/src/styles/globals.css +17 -15
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +14 -0
- package/dist/chunk-S4QRUQNW.mjs +0 -475
- package/dist/chunk-URGMJAE3.mjs +0 -1885
- package/dist/chunk-WNGWBVLV.mjs +0 -148
- package/dist/chunk-ZRSDX6OW.mjs +0 -385
- package/dist/{chunk-LLVQKSU3.mjs → chunk-GD4BJDJR.mjs} +3 -3
|
@@ -62,8 +62,9 @@ __export(sidebar_nav_exports, {
|
|
|
62
62
|
SidebarNav: () => SidebarNav
|
|
63
63
|
});
|
|
64
64
|
module.exports = __toCommonJS(sidebar_nav_exports);
|
|
65
|
-
var
|
|
66
|
-
var
|
|
65
|
+
var React3 = __toESM(require("react"));
|
|
66
|
+
var import_lucide_react3 = require("lucide-react");
|
|
67
|
+
var import_accordion2 = require("@base-ui/react/accordion");
|
|
67
68
|
|
|
68
69
|
// src/lib/utils.ts
|
|
69
70
|
var import_clsx = require("clsx");
|
|
@@ -104,26 +105,208 @@ function cn(...inputs) {
|
|
|
104
105
|
return twMerge((0, import_clsx.clsx)(inputs));
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
// src/lib/format-currency.ts
|
|
109
|
+
function formatCurrency(value, options) {
|
|
110
|
+
const { decimals = 0, showSign = false } = options != null ? options : {};
|
|
111
|
+
const abs = Math.abs(value);
|
|
112
|
+
const formatted = new Intl.NumberFormat("en-AU", {
|
|
113
|
+
style: "currency",
|
|
114
|
+
currency: "AUD",
|
|
115
|
+
minimumFractionDigits: decimals,
|
|
116
|
+
maximumFractionDigits: decimals
|
|
117
|
+
}).format(abs);
|
|
118
|
+
if (!showSign) return value < 0 ? `-${formatted}` : formatted;
|
|
119
|
+
if (value > 0) return `+${formatted}`;
|
|
120
|
+
if (value < 0) return `-${formatted}`;
|
|
121
|
+
return formatted;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/components/ui/accordion.tsx
|
|
125
|
+
var import_lucide_react = require("lucide-react");
|
|
126
|
+
var import_accordion = require("@base-ui/react/accordion");
|
|
127
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
128
|
+
function Accordion(props) {
|
|
129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_accordion.Accordion.Root, __spreadValues({ "data-slot": "accordion" }, props));
|
|
130
|
+
}
|
|
131
|
+
function AccordionItem(_a) {
|
|
132
|
+
var _b = _a, {
|
|
133
|
+
className
|
|
134
|
+
} = _b, props = __objRest(_b, [
|
|
135
|
+
"className"
|
|
136
|
+
]);
|
|
137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
138
|
+
import_accordion.Accordion.Item,
|
|
139
|
+
__spreadValues({
|
|
140
|
+
className: cn("border-b", className),
|
|
141
|
+
"data-slot": "accordion-item"
|
|
142
|
+
}, props)
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
function AccordionContent(_a) {
|
|
146
|
+
var _b = _a, {
|
|
147
|
+
className,
|
|
148
|
+
children
|
|
149
|
+
} = _b, props = __objRest(_b, [
|
|
150
|
+
"className",
|
|
151
|
+
"children"
|
|
152
|
+
]);
|
|
153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
154
|
+
import_accordion.Accordion.Panel,
|
|
155
|
+
__spreadProps(__spreadValues({
|
|
156
|
+
className: "overflow-hidden text-body-small h-(--accordion-panel-height) transition-[height] duration-200 ease-out data-starting-style:h-0 data-ending-style:h-0",
|
|
157
|
+
"data-slot": "accordion-content"
|
|
158
|
+
}, props), {
|
|
159
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("pb-4 text-muted-foreground", className), children })
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/components/ui/button.tsx
|
|
165
|
+
var import_react = require("react");
|
|
166
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
167
|
+
var import_lucide_react2 = require("lucide-react");
|
|
168
|
+
|
|
169
|
+
// src/lib/slot.tsx
|
|
170
|
+
var React = __toESM(require("react"));
|
|
171
|
+
function mergeRefs(...refs) {
|
|
172
|
+
return (value) => {
|
|
173
|
+
for (const ref of refs) {
|
|
174
|
+
if (typeof ref === "function") ref(value);
|
|
175
|
+
else if (ref !== null)
|
|
176
|
+
ref.current = value;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
var Slot = React.forwardRef(
|
|
181
|
+
(_a, forwardedRef) => {
|
|
182
|
+
var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
|
|
183
|
+
const child = React.Children.only(children);
|
|
184
|
+
if (!React.isValidElement(child)) return null;
|
|
185
|
+
const childProps = child.props;
|
|
186
|
+
const merged = __spreadValues({}, props);
|
|
187
|
+
for (const key of Object.keys(childProps)) {
|
|
188
|
+
if (key === "className") {
|
|
189
|
+
merged.className = [props.className, childProps.className].filter(Boolean).join(" ");
|
|
190
|
+
} else if (key === "style") {
|
|
191
|
+
merged.style = __spreadValues(__spreadValues({}, props.style), childProps.style);
|
|
192
|
+
} else if (key.startsWith("on") && typeof childProps[key] === "function") {
|
|
193
|
+
const parentHandler = props[key];
|
|
194
|
+
if (typeof parentHandler === "function") {
|
|
195
|
+
merged[key] = (...args) => {
|
|
196
|
+
childProps[key](...args);
|
|
197
|
+
parentHandler(...args);
|
|
198
|
+
};
|
|
199
|
+
} else {
|
|
200
|
+
merged[key] = childProps[key];
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
merged[key] = childProps[key];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const childRef = child.ref;
|
|
207
|
+
merged.ref = forwardedRef ? mergeRefs(forwardedRef, childRef) : childRef;
|
|
208
|
+
return React.cloneElement(
|
|
209
|
+
child,
|
|
210
|
+
merged
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
Slot.displayName = "Slot";
|
|
215
|
+
|
|
216
|
+
// src/components/ui/button.tsx
|
|
217
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
218
|
+
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
219
|
+
"inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 font-sans text-button whitespace-nowrap transition-all active:scale-[0.98] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
220
|
+
{
|
|
221
|
+
variants: {
|
|
222
|
+
variant: {
|
|
223
|
+
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
224
|
+
secondary: "bg-brand-secondary text-brand-secondary-foreground shadow-xs hover:bg-brand-secondary/80 focus-visible:ring-brand-secondary/30",
|
|
225
|
+
destructive: "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
|
|
226
|
+
outline: "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground focus-visible:ring-border/50 dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
227
|
+
"outline-primary": "border border-primary text-foreground bg-transparent shadow-xs hover:bg-primary/5 focus-visible:ring-primary/50",
|
|
228
|
+
"outline-secondary": "border border-brand-secondary text-brand-secondary bg-transparent shadow-xs hover:bg-brand-secondary/10 focus-visible:ring-brand-secondary/30",
|
|
229
|
+
ghost: "hover:bg-accent hover:text-accent-foreground hover:shadow-xs focus-visible:ring-border/50 dark:hover:bg-accent/50",
|
|
230
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
231
|
+
},
|
|
232
|
+
size: {
|
|
233
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
234
|
+
xs: "h-6 gap-1 px-2 text-button-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
235
|
+
sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
236
|
+
lg: "h-10 px-6 has-[>svg]:px-4",
|
|
237
|
+
icon: "size-9",
|
|
238
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
239
|
+
"icon-sm": "size-8",
|
|
240
|
+
"icon-lg": "size-10"
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
defaultVariants: {
|
|
244
|
+
variant: "default",
|
|
245
|
+
size: "default"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
var Button = (0, import_react.forwardRef)(function Button2(_a, ref) {
|
|
250
|
+
var _b = _a, {
|
|
251
|
+
className,
|
|
252
|
+
variant,
|
|
253
|
+
size,
|
|
254
|
+
asChild = false,
|
|
255
|
+
loading = false,
|
|
256
|
+
disabled,
|
|
257
|
+
type = "button",
|
|
258
|
+
children
|
|
259
|
+
} = _b, props = __objRest(_b, [
|
|
260
|
+
"className",
|
|
261
|
+
"variant",
|
|
262
|
+
"size",
|
|
263
|
+
"asChild",
|
|
264
|
+
"loading",
|
|
265
|
+
"disabled",
|
|
266
|
+
"type",
|
|
267
|
+
"children"
|
|
268
|
+
]);
|
|
269
|
+
const Comp = asChild ? Slot : "button";
|
|
270
|
+
const isIconOnly = size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg";
|
|
271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
272
|
+
Comp,
|
|
273
|
+
__spreadProps(__spreadValues({
|
|
274
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
275
|
+
"data-size": size,
|
|
276
|
+
"data-slot": "button",
|
|
277
|
+
"data-variant": variant,
|
|
278
|
+
disabled: loading || disabled,
|
|
279
|
+
ref,
|
|
280
|
+
type
|
|
281
|
+
}, props), {
|
|
282
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
283
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Loader2, { "aria-hidden": "true", className: "animate-spin" }),
|
|
284
|
+
!isIconOnly && children
|
|
285
|
+
] }) : children
|
|
286
|
+
})
|
|
287
|
+
);
|
|
288
|
+
});
|
|
289
|
+
|
|
107
290
|
// src/components/ui/tooltip.tsx
|
|
108
291
|
var import_tooltip = require("@base-ui/react/tooltip");
|
|
109
292
|
|
|
110
293
|
// src/lib/theme-provider.tsx
|
|
111
|
-
var
|
|
112
|
-
var
|
|
113
|
-
var ThemeVarsContext = (0,
|
|
294
|
+
var import_react2 = require("react");
|
|
295
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
296
|
+
var ThemeVarsContext = (0, import_react2.createContext)({});
|
|
114
297
|
function useThemeVars() {
|
|
115
|
-
return (0,
|
|
298
|
+
return (0, import_react2.useContext)(ThemeVarsContext);
|
|
116
299
|
}
|
|
117
300
|
|
|
118
301
|
// src/components/ui/tooltip.tsx
|
|
119
|
-
var
|
|
302
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
120
303
|
function TooltipProvider(_a) {
|
|
121
304
|
var _b = _a, {
|
|
122
305
|
delay = 0
|
|
123
306
|
} = _b, props = __objRest(_b, [
|
|
124
307
|
"delay"
|
|
125
308
|
]);
|
|
126
|
-
return /* @__PURE__ */ (0,
|
|
309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
127
310
|
import_tooltip.Tooltip.Provider,
|
|
128
311
|
__spreadValues({
|
|
129
312
|
"data-slot": "tooltip-provider",
|
|
@@ -133,11 +316,11 @@ function TooltipProvider(_a) {
|
|
|
133
316
|
}
|
|
134
317
|
function Tooltip(_a) {
|
|
135
318
|
var props = __objRest(_a, []);
|
|
136
|
-
return /* @__PURE__ */ (0,
|
|
319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
|
|
137
320
|
}
|
|
138
321
|
function TooltipTrigger(_a) {
|
|
139
322
|
var props = __objRest(_a, []);
|
|
140
|
-
return /* @__PURE__ */ (0,
|
|
323
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
|
|
141
324
|
}
|
|
142
325
|
function TooltipContent(_a) {
|
|
143
326
|
var _b = _a, {
|
|
@@ -154,7 +337,7 @@ function TooltipContent(_a) {
|
|
|
154
337
|
"style"
|
|
155
338
|
]);
|
|
156
339
|
const themeVars = useThemeVars();
|
|
157
|
-
return /* @__PURE__ */ (0,
|
|
340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
158
341
|
import_tooltip.Tooltip.Popup,
|
|
159
342
|
__spreadProps(__spreadValues({
|
|
160
343
|
className: cn(
|
|
@@ -166,30 +349,17 @@ function TooltipContent(_a) {
|
|
|
166
349
|
}, props), {
|
|
167
350
|
children: [
|
|
168
351
|
children,
|
|
169
|
-
/* @__PURE__ */ (0,
|
|
352
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.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" })
|
|
170
353
|
]
|
|
171
354
|
})
|
|
172
355
|
) }) });
|
|
173
356
|
}
|
|
174
357
|
|
|
175
358
|
// src/components/ui/sidebar-nav.tsx
|
|
176
|
-
var
|
|
359
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
177
360
|
function getInitials(name) {
|
|
178
361
|
return name.split(" ").filter(Boolean).map((word) => word[0]).join("").toUpperCase().slice(0, 2);
|
|
179
362
|
}
|
|
180
|
-
function formatCurrency(value, isNetItem = false) {
|
|
181
|
-
const abs = Math.abs(value);
|
|
182
|
-
const formatted = new Intl.NumberFormat("en-AU", {
|
|
183
|
-
style: "currency",
|
|
184
|
-
currency: "AUD",
|
|
185
|
-
minimumFractionDigits: 0,
|
|
186
|
-
maximumFractionDigits: 0
|
|
187
|
-
}).format(abs);
|
|
188
|
-
if (!isNetItem) return formatted;
|
|
189
|
-
if (value > 0) return `+${formatted}`;
|
|
190
|
-
if (value < 0) return `-${formatted}`;
|
|
191
|
-
return formatted;
|
|
192
|
-
}
|
|
193
363
|
function navIconCn(isActive) {
|
|
194
364
|
return cn(
|
|
195
365
|
"shrink-0 transition-colors",
|
|
@@ -198,19 +368,19 @@ function navIconCn(isActive) {
|
|
|
198
368
|
}
|
|
199
369
|
function NavTooltip({ label, collapsed, children }) {
|
|
200
370
|
if (!collapsed) return children;
|
|
201
|
-
return /* @__PURE__ */ (0,
|
|
202
|
-
/* @__PURE__ */ (0,
|
|
203
|
-
/* @__PURE__ */ (0,
|
|
371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Tooltip, { children: [
|
|
372
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipTrigger, { render: children }),
|
|
373
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipContent, { side: "right", children: label })
|
|
204
374
|
] });
|
|
205
375
|
}
|
|
206
376
|
function MetricsGroup({ group }) {
|
|
207
|
-
return /* @__PURE__ */ (0,
|
|
377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "border-b border-white/15 py-4 px-5 flex flex-col gap-1.5", children: group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
208
378
|
"div",
|
|
209
379
|
{
|
|
210
380
|
className: "flex items-center justify-between gap-2",
|
|
211
381
|
children: [
|
|
212
|
-
/* @__PURE__ */ (0,
|
|
213
|
-
/* @__PURE__ */ (0,
|
|
382
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-1 min-w-0", children: [
|
|
383
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
214
384
|
"span",
|
|
215
385
|
{
|
|
216
386
|
className: cn(
|
|
@@ -220,8 +390,8 @@ function MetricsGroup({ group }) {
|
|
|
220
390
|
children: item.name
|
|
221
391
|
}
|
|
222
392
|
),
|
|
223
|
-
item.info && /* @__PURE__ */ (0,
|
|
224
|
-
|
|
393
|
+
item.info && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
394
|
+
import_lucide_react3.Info,
|
|
225
395
|
{
|
|
226
396
|
size: 11,
|
|
227
397
|
strokeWidth: 2,
|
|
@@ -229,14 +399,14 @@ function MetricsGroup({ group }) {
|
|
|
229
399
|
}
|
|
230
400
|
)
|
|
231
401
|
] }),
|
|
232
|
-
/* @__PURE__ */ (0,
|
|
402
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
233
403
|
"span",
|
|
234
404
|
{
|
|
235
405
|
className: cn(
|
|
236
406
|
"text-sm font-semibold tabular-nums shrink-0 text-brand-secondary-foreground",
|
|
237
407
|
item.isNetItem && item.value < 0 && "text-destructive"
|
|
238
408
|
),
|
|
239
|
-
children: formatCurrency(item.value, item.isNetItem)
|
|
409
|
+
children: formatCurrency(item.value, { showSign: item.isNetItem })
|
|
240
410
|
}
|
|
241
411
|
)
|
|
242
412
|
]
|
|
@@ -251,29 +421,30 @@ function SidebarNavItemView({
|
|
|
251
421
|
}) {
|
|
252
422
|
var _a;
|
|
253
423
|
const Icon = item.icon;
|
|
254
|
-
return /* @__PURE__ */ (0,
|
|
255
|
-
|
|
424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NavTooltip, { label: item.title, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
425
|
+
Button,
|
|
256
426
|
{
|
|
257
427
|
type: "button",
|
|
428
|
+
variant: "ghost",
|
|
258
429
|
onClick: () => onNavigate == null ? void 0 : onNavigate(item.href),
|
|
259
430
|
className: cn(
|
|
260
|
-
"group
|
|
431
|
+
"group h-auto w-full items-center gap-3 py-2.5 text-base font-medium transition-colors",
|
|
261
432
|
"text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
|
|
262
433
|
collapsed ? "justify-center px-2" : cn(
|
|
263
|
-
"px-3 border-l-4",
|
|
434
|
+
"justify-start px-3 border-l-4",
|
|
264
435
|
item.isActive ? "bg-white/15 text-brand-secondary-foreground border-primary" : "border-transparent"
|
|
265
436
|
)
|
|
266
437
|
),
|
|
267
438
|
children: [
|
|
268
|
-
/* @__PURE__ */ (0,
|
|
439
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
269
440
|
Icon,
|
|
270
441
|
{
|
|
271
442
|
className: navIconCn((_a = item.isActive) != null ? _a : false),
|
|
272
|
-
size:
|
|
443
|
+
size: 24,
|
|
273
444
|
strokeWidth: 1.75
|
|
274
445
|
}
|
|
275
446
|
),
|
|
276
|
-
!collapsed && /* @__PURE__ */ (0,
|
|
447
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: item.title })
|
|
277
448
|
]
|
|
278
449
|
}
|
|
279
450
|
) });
|
|
@@ -286,96 +457,103 @@ function CollapsibleNavItem({
|
|
|
286
457
|
var _a, _b;
|
|
287
458
|
const Icon = item.icon;
|
|
288
459
|
const hasActiveChild = (_b = (_a = item.subItems) == null ? void 0 : _a.some((sub) => sub.isActive)) != null ? _b : false;
|
|
289
|
-
const [open, setOpen] =
|
|
290
|
-
|
|
460
|
+
const [open, setOpen] = React3.useState(hasActiveChild);
|
|
461
|
+
React3.useEffect(() => {
|
|
291
462
|
if (hasActiveChild) setOpen(true);
|
|
292
463
|
}, [hasActiveChild]);
|
|
293
464
|
if (collapsed) {
|
|
294
|
-
return /* @__PURE__ */ (0,
|
|
295
|
-
|
|
465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NavTooltip, { label: item.title, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
466
|
+
Button,
|
|
296
467
|
{
|
|
297
468
|
type: "button",
|
|
469
|
+
variant: "ghost",
|
|
298
470
|
onClick: () => onNavigate == null ? void 0 : onNavigate(item.href),
|
|
299
471
|
className: cn(
|
|
300
|
-
"group
|
|
472
|
+
"group h-auto w-full justify-center px-2 py-2.5 transition-colors",
|
|
301
473
|
"text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
|
|
302
474
|
hasActiveChild && "bg-white/15 text-brand-secondary-foreground"
|
|
303
475
|
),
|
|
304
|
-
children: /* @__PURE__ */ (0,
|
|
476
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
305
477
|
Icon,
|
|
306
478
|
{
|
|
307
479
|
className: navIconCn(hasActiveChild),
|
|
308
|
-
size:
|
|
480
|
+
size: 24,
|
|
309
481
|
strokeWidth: 1.75
|
|
310
482
|
}
|
|
311
483
|
)
|
|
312
484
|
}
|
|
313
485
|
) });
|
|
314
486
|
}
|
|
315
|
-
return /* @__PURE__ */ (0,
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
className:
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
import_lucide_react.ChevronDown,
|
|
339
|
-
{
|
|
340
|
-
className: cn(
|
|
341
|
-
"ml-auto shrink-0 text-brand-secondary-foreground/40 transition-transform duration-200",
|
|
342
|
-
open && "rotate-180"
|
|
487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
488
|
+
Accordion,
|
|
489
|
+
{
|
|
490
|
+
value: open ? [item.href] : [],
|
|
491
|
+
onValueChange: (values) => setOpen(values.length > 0),
|
|
492
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(AccordionItem, { className: "border-none", value: item.href, children: [
|
|
493
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_accordion2.Accordion.Header, { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
494
|
+
import_accordion2.Accordion.Trigger,
|
|
495
|
+
{
|
|
496
|
+
className: cn(
|
|
497
|
+
"group flex h-auto w-full items-center justify-start gap-3 px-3 py-2.5 text-base font-medium transition-colors",
|
|
498
|
+
"text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
|
|
499
|
+
"border-l-4 border-transparent",
|
|
500
|
+
hasActiveChild && "bg-white/15 text-brand-secondary-foreground border-primary"
|
|
501
|
+
),
|
|
502
|
+
children: [
|
|
503
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
504
|
+
Icon,
|
|
505
|
+
{
|
|
506
|
+
className: navIconCn(hasActiveChild),
|
|
507
|
+
size: 24,
|
|
508
|
+
strokeWidth: 1.75
|
|
509
|
+
}
|
|
343
510
|
),
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
onClick: () => onNavigate == null ? void 0 : onNavigate(sub.href),
|
|
356
|
-
className: cn(
|
|
357
|
-
"flex w-full items-center gap-2 py-1.5 pl-1 text-sm transition-colors",
|
|
358
|
-
"text-brand-secondary-foreground/50 hover:text-brand-secondary-foreground",
|
|
359
|
-
sub.isActive && "text-primary font-medium"
|
|
360
|
-
),
|
|
361
|
-
children: [
|
|
362
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
363
|
-
import_lucide_react.ChevronRight,
|
|
364
|
-
{
|
|
365
|
-
size: 11,
|
|
366
|
-
strokeWidth: 2,
|
|
367
|
-
className: cn(
|
|
368
|
-
"shrink-0",
|
|
369
|
-
sub.isActive ? "text-primary" : "text-brand-secondary-foreground/30"
|
|
511
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "flex-1 truncate text-left", children: item.title }),
|
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
513
|
+
import_lucide_react3.ChevronDown,
|
|
514
|
+
{
|
|
515
|
+
className: cn(
|
|
516
|
+
"ml-auto shrink-0 text-brand-secondary-foreground/40 transition-transform duration-200",
|
|
517
|
+
"group-data-[panel-open]:rotate-180"
|
|
518
|
+
),
|
|
519
|
+
size: 14,
|
|
520
|
+
strokeWidth: 2
|
|
521
|
+
}
|
|
370
522
|
)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
523
|
+
]
|
|
524
|
+
}
|
|
525
|
+
) }),
|
|
526
|
+
item.subItems && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionContent, { className: "p-0 text-inherit", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ml-9 border-l border-white/15 pl-3", children: item.subItems.map((sub) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
527
|
+
Button,
|
|
528
|
+
{
|
|
529
|
+
type: "button",
|
|
530
|
+
variant: "ghost",
|
|
531
|
+
onClick: () => onNavigate == null ? void 0 : onNavigate(sub.href),
|
|
532
|
+
className: cn(
|
|
533
|
+
"h-auto w-full justify-start gap-2 py-1.5 pl-1 text-sm transition-colors",
|
|
534
|
+
"text-brand-secondary-foreground/50 hover:text-brand-secondary-foreground",
|
|
535
|
+
sub.isActive && "text-primary font-medium"
|
|
536
|
+
),
|
|
537
|
+
children: [
|
|
538
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
539
|
+
import_lucide_react3.ChevronRight,
|
|
540
|
+
{
|
|
541
|
+
size: 11,
|
|
542
|
+
strokeWidth: 2,
|
|
543
|
+
className: cn(
|
|
544
|
+
"shrink-0",
|
|
545
|
+
sub.isActive ? "text-primary" : "text-brand-secondary-foreground/30"
|
|
546
|
+
)
|
|
547
|
+
}
|
|
548
|
+
),
|
|
549
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: sub.title })
|
|
550
|
+
]
|
|
551
|
+
},
|
|
552
|
+
sub.href
|
|
553
|
+
)) }) })
|
|
554
|
+
] })
|
|
555
|
+
}
|
|
556
|
+
);
|
|
379
557
|
}
|
|
380
558
|
function SidebarNav({
|
|
381
559
|
items,
|
|
@@ -389,93 +567,149 @@ function SidebarNav({
|
|
|
389
567
|
onCollapsedChange,
|
|
390
568
|
className
|
|
391
569
|
}) {
|
|
392
|
-
const [userMenuOpen, setUserMenuOpen] =
|
|
393
|
-
|
|
570
|
+
const [userMenuOpen, setUserMenuOpen] = React3.useState(false);
|
|
571
|
+
const navScrollRef = React3.useRef(null);
|
|
572
|
+
const expandedScrollRef = React3.useRef(0);
|
|
573
|
+
React3.useEffect(() => {
|
|
574
|
+
if (collapsed) setUserMenuOpen(false);
|
|
575
|
+
}, [collapsed]);
|
|
576
|
+
React3.useLayoutEffect(() => {
|
|
577
|
+
const nav = navScrollRef.current;
|
|
578
|
+
if (!nav) return;
|
|
579
|
+
if (!collapsed) {
|
|
580
|
+
nav.scrollTop = expandedScrollRef.current;
|
|
581
|
+
}
|
|
582
|
+
return () => {
|
|
583
|
+
if (!collapsed && nav) {
|
|
584
|
+
expandedScrollRef.current = nav.scrollTop;
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
}, [collapsed]);
|
|
588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
394
589
|
"nav",
|
|
395
590
|
{
|
|
396
591
|
"data-slot": "sidebar-nav",
|
|
397
592
|
"data-collapsed": collapsed,
|
|
398
593
|
className: cn(
|
|
399
|
-
|
|
594
|
+
// Force dark-mode CSS variable resolution — sidebar is always dark-backgrounded
|
|
595
|
+
// regardless of system theme, so semantic tokens (destructive, success, etc.)
|
|
596
|
+
// must use their dark-mode values to maintain WCAG contrast.
|
|
597
|
+
"dark flex h-full flex-col bg-brand-secondary text-brand-secondary-foreground",
|
|
400
598
|
"transition-all duration-200 ease-in-out",
|
|
401
599
|
collapsed ? "w-14" : "w-[279px]",
|
|
402
600
|
className
|
|
403
601
|
),
|
|
404
602
|
children: [
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
src: logo,
|
|
409
|
-
alt: "Logo",
|
|
410
|
-
className: "h-8 w-auto object-contain object-left",
|
|
411
|
-
style: { filter: "brightness(0) invert(1)" }
|
|
412
|
-
}
|
|
413
|
-
) }),
|
|
414
|
-
collapsed && logoCollapsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center justify-center border-b border-white/15 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
415
|
-
"img",
|
|
416
|
-
{
|
|
417
|
-
src: logoCollapsed,
|
|
418
|
-
alt: "Logo",
|
|
419
|
-
className: "h-8 w-8 object-contain",
|
|
420
|
-
style: { filter: "brightness(0) invert(1)" }
|
|
421
|
-
}
|
|
422
|
-
) }),
|
|
423
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "border-b border-white/15", children: [
|
|
424
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NavTooltip, { label: userName, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
425
|
-
"button",
|
|
603
|
+
(logo || logoCollapsed) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative flex items-center border-b border-white/15 py-4 overflow-hidden", children: [
|
|
604
|
+
logo && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
605
|
+
"img",
|
|
426
606
|
{
|
|
427
|
-
|
|
428
|
-
|
|
607
|
+
src: logo,
|
|
608
|
+
alt: "Logo",
|
|
429
609
|
className: cn(
|
|
430
|
-
"
|
|
431
|
-
"
|
|
432
|
-
collapsed && "justify-center px-2 py-4"
|
|
610
|
+
"h-8 w-auto object-contain object-left px-5 transition-opacity duration-200",
|
|
611
|
+
collapsed ? "opacity-0" : "opacity-100"
|
|
433
612
|
),
|
|
434
|
-
|
|
435
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground", children: getInitials(userName) }),
|
|
436
|
-
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
437
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "flex-1 truncate text-left font-medium text-brand-secondary-foreground", children: userName }),
|
|
438
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
439
|
-
import_lucide_react.ChevronDown,
|
|
440
|
-
{
|
|
441
|
-
className: cn(
|
|
442
|
-
"shrink-0 text-brand-secondary-foreground/50 transition-transform duration-200",
|
|
443
|
-
userMenuOpen && "rotate-180"
|
|
444
|
-
),
|
|
445
|
-
size: 16,
|
|
446
|
-
strokeWidth: 2
|
|
447
|
-
}
|
|
448
|
-
)
|
|
449
|
-
] })
|
|
450
|
-
]
|
|
613
|
+
style: { filter: "brightness(0) invert(1)" }
|
|
451
614
|
}
|
|
452
|
-
)
|
|
453
|
-
|
|
454
|
-
"
|
|
615
|
+
),
|
|
616
|
+
logoCollapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
617
|
+
"img",
|
|
455
618
|
{
|
|
456
|
-
|
|
457
|
-
|
|
619
|
+
src: logoCollapsed,
|
|
620
|
+
alt: "Logo",
|
|
458
621
|
className: cn(
|
|
459
|
-
"
|
|
460
|
-
"
|
|
622
|
+
"absolute inset-y-0 left-0 right-0 m-auto h-8 w-8 object-contain transition-opacity duration-200",
|
|
623
|
+
collapsed ? "opacity-100" : "opacity-0"
|
|
461
624
|
),
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
625
|
+
style: { filter: "brightness(0) invert(1)" }
|
|
626
|
+
}
|
|
627
|
+
)
|
|
628
|
+
] }),
|
|
629
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative border-b border-white/15", children: [
|
|
630
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
631
|
+
"div",
|
|
632
|
+
{
|
|
633
|
+
className: cn(
|
|
634
|
+
collapsed ? "opacity-0 pointer-events-none" : "opacity-100"
|
|
635
|
+
),
|
|
636
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
637
|
+
Accordion,
|
|
638
|
+
{
|
|
639
|
+
value: userMenuOpen ? ["user-menu"] : [],
|
|
640
|
+
onValueChange: (values) => setUserMenuOpen(values.length > 0),
|
|
641
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(AccordionItem, { className: "border-none", value: "user-menu", children: [
|
|
642
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_accordion2.Accordion.Header, { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
643
|
+
import_accordion2.Accordion.Trigger,
|
|
644
|
+
{
|
|
645
|
+
className: cn(
|
|
646
|
+
"group flex h-auto w-full items-center justify-start gap-3 px-5 py-5 text-base transition-colors",
|
|
647
|
+
"text-brand-secondary-foreground hover:bg-white/10"
|
|
648
|
+
),
|
|
649
|
+
children: [
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground", children: getInitials(userName) }),
|
|
651
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "flex-1 truncate text-left font-medium text-brand-secondary-foreground", children: userName }),
|
|
652
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
653
|
+
import_lucide_react3.ChevronDown,
|
|
654
|
+
{
|
|
655
|
+
className: "ml-auto shrink-0 text-brand-secondary-foreground/50 transition-transform duration-200 group-data-[panel-open]:rotate-180",
|
|
656
|
+
size: 16,
|
|
657
|
+
strokeWidth: 2
|
|
658
|
+
}
|
|
659
|
+
)
|
|
660
|
+
]
|
|
661
|
+
}
|
|
662
|
+
) }),
|
|
663
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionContent, { className: "p-0 text-inherit", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "border-t border-white/15 bg-black/20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
664
|
+
Button,
|
|
665
|
+
{
|
|
666
|
+
type: "button",
|
|
667
|
+
variant: "ghost",
|
|
668
|
+
onClick: onLogout,
|
|
669
|
+
className: cn(
|
|
670
|
+
"h-auto w-full justify-start gap-3 px-5 py-3 text-base",
|
|
671
|
+
"text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground transition-colors"
|
|
672
|
+
),
|
|
673
|
+
children: [
|
|
674
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
675
|
+
import_lucide_react3.LogOut,
|
|
676
|
+
{
|
|
677
|
+
size: 16,
|
|
678
|
+
strokeWidth: 1.75,
|
|
679
|
+
className: "shrink-0 text-destructive"
|
|
680
|
+
}
|
|
681
|
+
),
|
|
682
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Logout" })
|
|
683
|
+
]
|
|
684
|
+
}
|
|
685
|
+
) }) })
|
|
686
|
+
] })
|
|
687
|
+
}
|
|
688
|
+
)
|
|
689
|
+
}
|
|
690
|
+
),
|
|
691
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NavTooltip, { label: userName, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
692
|
+
"div",
|
|
693
|
+
{
|
|
694
|
+
className: cn(
|
|
695
|
+
"absolute inset-0 flex items-center justify-center transition-opacity duration-200",
|
|
696
|
+
collapsed ? "opacity-100" : "opacity-0 pointer-events-none"
|
|
697
|
+
),
|
|
698
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground", children: getInitials(userName) })
|
|
473
699
|
}
|
|
474
700
|
) })
|
|
475
701
|
] }),
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
702
|
+
!!(metricsGroups == null ? void 0 : metricsGroups.length) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
703
|
+
Accordion,
|
|
704
|
+
{
|
|
705
|
+
value: !collapsed ? ["metrics"] : [],
|
|
706
|
+
onValueChange: () => {
|
|
707
|
+
},
|
|
708
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionItem, { className: "border-none", value: "metrics", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionContent, { className: "p-0 text-inherit", children: metricsGroups.map((group, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MetricsGroup, { group }, i)) }) })
|
|
709
|
+
}
|
|
710
|
+
),
|
|
711
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: navScrollRef, className: "flex flex-col overflow-y-auto py-3", children: items.map(
|
|
712
|
+
(item) => item.isCollapsible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
479
713
|
CollapsibleNavItem,
|
|
480
714
|
{
|
|
481
715
|
item,
|
|
@@ -483,7 +717,7 @@ function SidebarNav({
|
|
|
483
717
|
onNavigate
|
|
484
718
|
},
|
|
485
719
|
item.href
|
|
486
|
-
) : /* @__PURE__ */ (0,
|
|
720
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
487
721
|
SidebarNavItemView,
|
|
488
722
|
{
|
|
489
723
|
item,
|
|
@@ -493,38 +727,39 @@ function SidebarNav({
|
|
|
493
727
|
item.href
|
|
494
728
|
)
|
|
495
729
|
) }),
|
|
496
|
-
onCollapsedChange && /* @__PURE__ */ (0,
|
|
730
|
+
onCollapsedChange && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mt-auto border-t border-white/15 bg-white/8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
497
731
|
NavTooltip,
|
|
498
732
|
{
|
|
499
733
|
label: collapsed ? "Expand" : "Collapse",
|
|
500
734
|
collapsed,
|
|
501
|
-
children: /* @__PURE__ */ (0,
|
|
502
|
-
|
|
735
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
736
|
+
Button,
|
|
503
737
|
{
|
|
504
738
|
type: "button",
|
|
739
|
+
variant: "ghost",
|
|
505
740
|
onClick: () => onCollapsedChange(!collapsed),
|
|
506
741
|
className: cn(
|
|
507
|
-
"
|
|
742
|
+
"h-12 w-full justify-start gap-3 px-3 py-3 transition-colors",
|
|
508
743
|
"text-brand-secondary-foreground/80 hover:bg-white/10 hover:text-brand-secondary-foreground",
|
|
509
744
|
collapsed && "justify-center px-2"
|
|
510
745
|
),
|
|
511
746
|
children: [
|
|
512
|
-
collapsed ? /* @__PURE__ */ (0,
|
|
513
|
-
|
|
747
|
+
collapsed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
748
|
+
import_lucide_react3.PanelLeftOpen,
|
|
514
749
|
{
|
|
515
|
-
size:
|
|
750
|
+
size: 24,
|
|
516
751
|
strokeWidth: 1.75,
|
|
517
752
|
className: "shrink-0"
|
|
518
753
|
}
|
|
519
|
-
) : /* @__PURE__ */ (0,
|
|
520
|
-
|
|
754
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
755
|
+
import_lucide_react3.PanelLeftClose,
|
|
521
756
|
{
|
|
522
|
-
size:
|
|
757
|
+
size: 24,
|
|
523
758
|
strokeWidth: 1.75,
|
|
524
759
|
className: "shrink-0"
|
|
525
760
|
}
|
|
526
761
|
),
|
|
527
|
-
!collapsed && /* @__PURE__ */ (0,
|
|
762
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-sm", children: "Collapse" })
|
|
528
763
|
]
|
|
529
764
|
}
|
|
530
765
|
)
|