@pol-studios/ui 1.0.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/dist/adapters/index.js +359 -0
- package/dist/auth/index.js +588 -0
- package/dist/canvas-UVNDA54X.node +0 -0
- package/dist/cards/index.js +872 -0
- package/dist/charts/index.js +54148 -0
- package/dist/components/chat-agent/index.js +21434 -0
- package/dist/components/index.js +148416 -0
- package/dist/contexts/index.js +188 -0
- package/dist/crud/index.js +6550 -0
- package/dist/data/index.js +372 -0
- package/dist/feedback/index.js +9534 -0
- package/dist/file/index.js +256 -0
- package/dist/forms/index.js +504 -0
- package/dist/hooks/index.js +345 -0
- package/dist/index.js +15650 -0
- package/dist/nav/index.js +1556 -0
- package/dist/navbar/index.js +45262 -0
- package/dist/primitives/index.js +15646 -0
- package/dist/providers/index.js +1927 -0
- package/dist/types/index.js +1 -0
- package/package.json +226 -0
- package/src/styles/globals.css +157 -0
|
@@ -0,0 +1,1556 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/nav/BottomNav.tsx
|
|
4
|
+
import { Tooltip } from "flowbite-react";
|
|
5
|
+
import { HiCog } from "react-icons/hi";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
function BottomNav({ settingsRoute = "/settings" }) {
|
|
8
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center gap-x-5", children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Tooltip, { content: "Settings page", children: /* @__PURE__ */ jsxs(
|
|
9
|
+
"a",
|
|
10
|
+
{
|
|
11
|
+
href: settingsRoute,
|
|
12
|
+
className: "inline-flex cursor-pointer justify-center rounded p-2 text-text-500 hover:bg-muted-100 hover:text-text-900 ",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Settings page" }),
|
|
15
|
+
/* @__PURE__ */ jsx(HiCog, { className: "text-2xl text-text-400 text-text-500 hover:text-text-900 " })
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
) }) }) });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/nav/MenuToggle.tsx
|
|
22
|
+
import { motion } from "framer-motion";
|
|
23
|
+
|
|
24
|
+
// src/primitives/button.tsx
|
|
25
|
+
import * as React from "react";
|
|
26
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
27
|
+
import { cva } from "class-variance-authority";
|
|
28
|
+
import { cn } from "@pol-studios/utils";
|
|
29
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
30
|
+
var buttonVariants = cva(
|
|
31
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
32
|
+
{
|
|
33
|
+
variants: {
|
|
34
|
+
variant: {
|
|
35
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
36
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
37
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
38
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
39
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
40
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
41
|
+
},
|
|
42
|
+
size: {
|
|
43
|
+
default: "h-10 px-4 py-2",
|
|
44
|
+
sm: "h-9 rounded-md px-3",
|
|
45
|
+
lg: "h-11 rounded-md px-8",
|
|
46
|
+
icon: "h-10 w-10"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
defaultVariants: {
|
|
50
|
+
variant: "default",
|
|
51
|
+
size: "default"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
var Button = React.forwardRef(
|
|
56
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
57
|
+
const Comp = asChild ? Slot : "button";
|
|
58
|
+
return /* @__PURE__ */ jsx2(
|
|
59
|
+
Comp,
|
|
60
|
+
{
|
|
61
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
62
|
+
ref,
|
|
63
|
+
...props
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
Button.displayName = "Button";
|
|
69
|
+
|
|
70
|
+
// src/nav/MenuToggle.tsx
|
|
71
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
72
|
+
var Path = (props) => /* @__PURE__ */ jsx3(
|
|
73
|
+
motion.path,
|
|
74
|
+
{
|
|
75
|
+
animate: props.isOpen ? "open" : "closed",
|
|
76
|
+
fill: "transparent",
|
|
77
|
+
strokeWidth: "3",
|
|
78
|
+
strokeLinecap: "round",
|
|
79
|
+
...props
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
var MenuToggle = ({ toggle, isOpen }) => {
|
|
83
|
+
return /* @__PURE__ */ jsx3(Button, { onClick: toggle, className: "z-[100000] p-2", variant: "ghost", "data-testid": "nav-button", children: /* @__PURE__ */ jsxs2("svg", { width: "23", height: "23", className: "stroke-text-50 ", viewBox: "0 0 22 18", children: [
|
|
84
|
+
/* @__PURE__ */ jsx3(
|
|
85
|
+
Path,
|
|
86
|
+
{
|
|
87
|
+
isOpen,
|
|
88
|
+
variants: {
|
|
89
|
+
closed: { d: "M 2 2.5 L 20 2.5" },
|
|
90
|
+
open: { d: "M 3 16.5 L 17 2.5" }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsx3(
|
|
95
|
+
Path,
|
|
96
|
+
{
|
|
97
|
+
isOpen,
|
|
98
|
+
d: "M 2 9.423 L 20 9.423",
|
|
99
|
+
variants: {
|
|
100
|
+
closed: { opacity: 1 },
|
|
101
|
+
open: { opacity: 0 }
|
|
102
|
+
},
|
|
103
|
+
transition: { duration: 0.1 }
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
/* @__PURE__ */ jsx3(
|
|
107
|
+
Path,
|
|
108
|
+
{
|
|
109
|
+
isOpen,
|
|
110
|
+
variants: {
|
|
111
|
+
closed: { d: "M 2 16.346 L 20 16.346" },
|
|
112
|
+
open: { d: "M 3 2.5 L 17 16.346" }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
] }) });
|
|
117
|
+
};
|
|
118
|
+
var MenuToggle_default = MenuToggle;
|
|
119
|
+
|
|
120
|
+
// src/nav/NavBarGroupItem.tsx
|
|
121
|
+
import { Collapse } from "@mui/material";
|
|
122
|
+
import { useState } from "react";
|
|
123
|
+
import { ChevronUp, ChevronDown } from "lucide-react";
|
|
124
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
125
|
+
function NavBarGroupItem({ title, icon, children, className }) {
|
|
126
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
127
|
+
return /* @__PURE__ */ jsxs3("div", { className, children: [
|
|
128
|
+
/* @__PURE__ */ jsxs3(
|
|
129
|
+
"div",
|
|
130
|
+
{
|
|
131
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
132
|
+
className: "grid cursor-pointer grid-flow-col grid-cols-[auto_1fr]\n rounded-md bg-background-950 px-2 py-0.5 transition-all hover:bg-slate-100\n ",
|
|
133
|
+
children: [
|
|
134
|
+
icon && /* @__PURE__ */ jsx4("span", { className: "my-auto mr-5", children: icon }),
|
|
135
|
+
/* @__PURE__ */ jsx4("span", { className: "text-left align-bottom leading-[2.5rem] font-semibold", children: title }),
|
|
136
|
+
/* @__PURE__ */ jsx4("span", { className: "mb-auto ml-5 mr-0.5 mt-auto", children: isExpanded ? /* @__PURE__ */ jsx4(ChevronUp, {}) : /* @__PURE__ */ jsx4(ChevronDown, {}) })
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
),
|
|
140
|
+
/* @__PURE__ */ jsx4(Collapse, { in: isExpanded, timeout: "auto", unmountOnExit: true, style: {}, children })
|
|
141
|
+
] });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/nav/UserProfileName.tsx
|
|
145
|
+
import { cn as cn2 } from "@pol-studios/utils";
|
|
146
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
147
|
+
function UserProfileName({
|
|
148
|
+
userId,
|
|
149
|
+
className,
|
|
150
|
+
size = "1rem",
|
|
151
|
+
firstName,
|
|
152
|
+
lastName,
|
|
153
|
+
isLoading = false
|
|
154
|
+
}) {
|
|
155
|
+
if (isLoading) {
|
|
156
|
+
return /* @__PURE__ */ jsx5("span", { className: cn2("animate-pulse bg-muted-200 rounded h-4 w-24 inline-block", className) });
|
|
157
|
+
}
|
|
158
|
+
return /* @__PURE__ */ jsx5("span", { className, style: { fontSize: size }, children: userId ? (firstName ?? "") + " " + (lastName ?? "") : "Application" });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/nav/UserProfilePicture.tsx
|
|
162
|
+
import { cn as cn4, isUsable } from "@pol-studios/utils";
|
|
163
|
+
|
|
164
|
+
// src/primitives/spinner.tsx
|
|
165
|
+
import { Loader2Icon } from "lucide-react";
|
|
166
|
+
import { cn as cn3 } from "@pol-studios/utils";
|
|
167
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
168
|
+
function Spinner({ className, ...props }) {
|
|
169
|
+
return /* @__PURE__ */ jsx6(
|
|
170
|
+
Loader2Icon,
|
|
171
|
+
{
|
|
172
|
+
role: "status",
|
|
173
|
+
"aria-label": "Loading",
|
|
174
|
+
className: cn3("size-4 animate-spin", className),
|
|
175
|
+
...props
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/nav/UserProfilePicture.tsx
|
|
181
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
182
|
+
function UserProfilePicture({
|
|
183
|
+
userId,
|
|
184
|
+
className = "w-10 h-10",
|
|
185
|
+
size = "1rem",
|
|
186
|
+
onMouseEnter,
|
|
187
|
+
onMouseLeave,
|
|
188
|
+
firstName,
|
|
189
|
+
lastName,
|
|
190
|
+
profileImageUrl,
|
|
191
|
+
isLoading = false
|
|
192
|
+
}) {
|
|
193
|
+
const initials = (firstName?.[0] ?? "") + (lastName?.[0] ?? "");
|
|
194
|
+
const fallBack = /* @__PURE__ */ jsx7("span", { className: cn4("m-auto p-0 leading-[unset] text-text-50 text-sm"), children: firstName || lastName ? initials : "" });
|
|
195
|
+
const hasProfilePath = isUsable(profileImageUrl);
|
|
196
|
+
return /* @__PURE__ */ jsx7(
|
|
197
|
+
"div",
|
|
198
|
+
{
|
|
199
|
+
onMouseEnter: () => {
|
|
200
|
+
onMouseEnter && onMouseEnter();
|
|
201
|
+
},
|
|
202
|
+
onMouseLeave: () => {
|
|
203
|
+
onMouseLeave && onMouseLeave();
|
|
204
|
+
},
|
|
205
|
+
className: cn4(
|
|
206
|
+
"m-auto cursor-pointer rounded-full bg-primary-700 transition hover:bg-primary-800 flex items-center justify-center",
|
|
207
|
+
className
|
|
208
|
+
),
|
|
209
|
+
children: isLoading ? /* @__PURE__ */ jsx7("div", { className: "center-Items grid h-full", children: /* @__PURE__ */ jsx7(
|
|
210
|
+
Spinner,
|
|
211
|
+
{
|
|
212
|
+
className: cn4("m-auto h-full", className)
|
|
213
|
+
}
|
|
214
|
+
) }) : hasProfilePath ? /* @__PURE__ */ jsx7(
|
|
215
|
+
"img",
|
|
216
|
+
{
|
|
217
|
+
src: profileImageUrl,
|
|
218
|
+
alt: `${firstName} ${lastName}`,
|
|
219
|
+
className: cn4("transition rounded-full object-cover", className)
|
|
220
|
+
}
|
|
221
|
+
) : fallBack
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/nav/aceternity/breadcrumb.config.ts
|
|
227
|
+
var globalBreadcrumbConfigs = [];
|
|
228
|
+
var globalHierarchicalConfigs = [];
|
|
229
|
+
var setBreadcrumbConfigs = (configs) => {
|
|
230
|
+
globalBreadcrumbConfigs = configs;
|
|
231
|
+
};
|
|
232
|
+
var setHierarchicalBreadcrumbConfigs = (configs) => {
|
|
233
|
+
globalHierarchicalConfigs = configs;
|
|
234
|
+
globalBreadcrumbConfigs = flattenHierarchicalConfigs(configs);
|
|
235
|
+
};
|
|
236
|
+
var flattenHierarchicalConfigs = (configs) => {
|
|
237
|
+
const flattened = [];
|
|
238
|
+
const flatten = (config, parentPattern = "", parentHref = "", inheritedSegments = []) => {
|
|
239
|
+
let fullPattern;
|
|
240
|
+
if (parentPattern === "" && config.pattern.startsWith("/")) {
|
|
241
|
+
fullPattern = config.pattern;
|
|
242
|
+
} else {
|
|
243
|
+
const childPattern = config.pattern.startsWith("/") ? config.pattern.substring(1) : config.pattern;
|
|
244
|
+
fullPattern = parentPattern + "/" + childPattern;
|
|
245
|
+
}
|
|
246
|
+
const segments = config.segments.map((segment) => {
|
|
247
|
+
let href = segment.href;
|
|
248
|
+
if (segment.path !== void 0) {
|
|
249
|
+
if (segment.isAbsolute || segment.path.startsWith("/")) {
|
|
250
|
+
href = segment.path;
|
|
251
|
+
} else {
|
|
252
|
+
const baseHref = parentHref || fullPattern;
|
|
253
|
+
const relativePath = segment.path.startsWith("/") ? segment.path : "/" + segment.path;
|
|
254
|
+
if (baseHref.includes(":")) {
|
|
255
|
+
href = (pathname) => {
|
|
256
|
+
const dynamicValues = extractDynamicValues(pathname, fullPattern);
|
|
257
|
+
let resolvedBaseHref = baseHref;
|
|
258
|
+
Object.entries(dynamicValues).forEach(([key, value]) => {
|
|
259
|
+
resolvedBaseHref = resolvedBaseHref.replace(`:${key}`, value);
|
|
260
|
+
});
|
|
261
|
+
return resolvedBaseHref + relativePath;
|
|
262
|
+
};
|
|
263
|
+
} else {
|
|
264
|
+
href = baseHref + relativePath;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
} else if (segment.href === void 0) {
|
|
268
|
+
href = fullPattern;
|
|
269
|
+
}
|
|
270
|
+
if (typeof href === "string" && href.includes(":")) {
|
|
271
|
+
const originalHref = href;
|
|
272
|
+
href = (pathname) => {
|
|
273
|
+
const dynamicValues = extractDynamicValues(pathname, fullPattern);
|
|
274
|
+
let resolvedHref = originalHref;
|
|
275
|
+
Object.entries(dynamicValues).forEach(([key, value]) => {
|
|
276
|
+
resolvedHref = resolvedHref.replace(`:${key}`, value);
|
|
277
|
+
});
|
|
278
|
+
return resolvedHref;
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
label: segment.label,
|
|
283
|
+
href,
|
|
284
|
+
icon: segment.icon,
|
|
285
|
+
dynamic: segment.dynamic,
|
|
286
|
+
dynamicLabel: segment.dynamicLabel,
|
|
287
|
+
path: segment.path,
|
|
288
|
+
isAbsolute: segment.isAbsolute
|
|
289
|
+
};
|
|
290
|
+
});
|
|
291
|
+
const allSegments = [...inheritedSegments, ...segments];
|
|
292
|
+
flattened.push({
|
|
293
|
+
pattern: fullPattern,
|
|
294
|
+
segments: allSegments,
|
|
295
|
+
priority: config.priority
|
|
296
|
+
});
|
|
297
|
+
if (config.children) {
|
|
298
|
+
config.children.forEach(
|
|
299
|
+
(child) => flatten(child, fullPattern, fullPattern, allSegments)
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
configs.forEach((config) => flatten(config));
|
|
304
|
+
return flattened;
|
|
305
|
+
};
|
|
306
|
+
var addBreadcrumbConfigs = (configs) => {
|
|
307
|
+
globalBreadcrumbConfigs = [...globalBreadcrumbConfigs, ...configs];
|
|
308
|
+
};
|
|
309
|
+
var addHierarchicalBreadcrumbConfigs = (configs) => {
|
|
310
|
+
globalHierarchicalConfigs = [...globalHierarchicalConfigs, ...configs];
|
|
311
|
+
globalBreadcrumbConfigs = [
|
|
312
|
+
...globalBreadcrumbConfigs,
|
|
313
|
+
...flattenHierarchicalConfigs(configs)
|
|
314
|
+
];
|
|
315
|
+
};
|
|
316
|
+
var getBreadcrumbConfigs = () => {
|
|
317
|
+
return globalBreadcrumbConfigs;
|
|
318
|
+
};
|
|
319
|
+
var getHierarchicalBreadcrumbConfigs = () => {
|
|
320
|
+
return globalHierarchicalConfigs;
|
|
321
|
+
};
|
|
322
|
+
var clearBreadcrumbConfigs = () => {
|
|
323
|
+
globalBreadcrumbConfigs = [];
|
|
324
|
+
globalHierarchicalConfigs = [];
|
|
325
|
+
};
|
|
326
|
+
var findParentConfig = (pattern, allConfigs) => {
|
|
327
|
+
const patternSegments = pattern.split("/").filter(Boolean);
|
|
328
|
+
if (patternSegments.length === 0) {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
for (let i = patternSegments.length - 1; i > 0; i--) {
|
|
332
|
+
const parentPattern = "/" + patternSegments.slice(0, i).join("/");
|
|
333
|
+
const parentConfig = allConfigs.find((c) => c.pattern === parentPattern);
|
|
334
|
+
if (parentConfig) {
|
|
335
|
+
return parentConfig;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const rootConfig = allConfigs.find((c) => c.pattern === "/");
|
|
339
|
+
return rootConfig || null;
|
|
340
|
+
};
|
|
341
|
+
var buildInheritedBreadcrumbConfig = (config, allConfigs, visitedPatterns = /* @__PURE__ */ new Set()) => {
|
|
342
|
+
if (visitedPatterns.has(config.pattern)) {
|
|
343
|
+
console.warn(
|
|
344
|
+
`Circular reference detected in breadcrumb pattern: ${config.pattern}`
|
|
345
|
+
);
|
|
346
|
+
return config;
|
|
347
|
+
}
|
|
348
|
+
visitedPatterns.add(config.pattern);
|
|
349
|
+
const parentConfig = findParentConfig(config.pattern, allConfigs);
|
|
350
|
+
if (!parentConfig) {
|
|
351
|
+
return config;
|
|
352
|
+
}
|
|
353
|
+
const builtParent = buildInheritedBreadcrumbConfig(
|
|
354
|
+
parentConfig,
|
|
355
|
+
allConfigs,
|
|
356
|
+
visitedPatterns
|
|
357
|
+
);
|
|
358
|
+
return {
|
|
359
|
+
...config,
|
|
360
|
+
segments: [...builtParent.segments, ...config.segments]
|
|
361
|
+
};
|
|
362
|
+
};
|
|
363
|
+
var findBreadcrumbConfig = (pathname) => {
|
|
364
|
+
const sortedConfigs = [...globalBreadcrumbConfigs].sort(
|
|
365
|
+
(a, b) => (b.priority || 0) - (a.priority || 0)
|
|
366
|
+
);
|
|
367
|
+
for (const config of sortedConfigs) {
|
|
368
|
+
const matches = matchesPattern(pathname, config.pattern);
|
|
369
|
+
if (matches) {
|
|
370
|
+
return config;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
374
|
+
const prefixCandidates = sortedConfigs.filter((c) => matchesPrefix(pathname, c.pattern)).sort((a, b) => {
|
|
375
|
+
const aLen = a.pattern.split("/").filter(Boolean).length;
|
|
376
|
+
const bLen = b.pattern.split("/").filter(Boolean).length;
|
|
377
|
+
if (bLen !== aLen) return bLen - aLen;
|
|
378
|
+
return (b.priority || 0) - (a.priority || 0);
|
|
379
|
+
});
|
|
380
|
+
if (prefixCandidates.length > 0) {
|
|
381
|
+
const best = prefixCandidates[0];
|
|
382
|
+
const inherited = buildInheritedBreadcrumbConfig(best, sortedConfigs);
|
|
383
|
+
const patternSegments = best.pattern.split("/").filter(Boolean);
|
|
384
|
+
const remaining = pathSegments.slice(patternSegments.length);
|
|
385
|
+
let currentPath2 = best.pattern === "/" ? "" : best.pattern;
|
|
386
|
+
const remainingSegments = [];
|
|
387
|
+
remaining.forEach((segment) => {
|
|
388
|
+
currentPath2 += `/${segment}`;
|
|
389
|
+
const isId = /^\d+$/.test(segment);
|
|
390
|
+
remainingSegments.push({
|
|
391
|
+
label: isId ? `Item ${segment}` : segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, " "),
|
|
392
|
+
href: currentPath2,
|
|
393
|
+
icon: void 0
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
return {
|
|
397
|
+
pattern: pathname,
|
|
398
|
+
segments: normalizeSegments([
|
|
399
|
+
...inherited.segments,
|
|
400
|
+
...remainingSegments
|
|
401
|
+
]),
|
|
402
|
+
priority: inherited.priority ?? 0
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
const fallbackSegments = [
|
|
406
|
+
{
|
|
407
|
+
label: "Home",
|
|
408
|
+
href: "/",
|
|
409
|
+
icon: void 0
|
|
410
|
+
}
|
|
411
|
+
];
|
|
412
|
+
let currentPath = "";
|
|
413
|
+
pathSegments.forEach((segment) => {
|
|
414
|
+
currentPath += `/${segment}`;
|
|
415
|
+
const isId = /^\d+$/.test(segment);
|
|
416
|
+
fallbackSegments.push({
|
|
417
|
+
label: isId ? `Item ${segment}` : segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, " "),
|
|
418
|
+
href: currentPath,
|
|
419
|
+
icon: void 0
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
return {
|
|
423
|
+
pattern: pathname,
|
|
424
|
+
segments: fallbackSegments,
|
|
425
|
+
priority: 0
|
|
426
|
+
};
|
|
427
|
+
};
|
|
428
|
+
var matchesPattern = (pathname, pattern) => {
|
|
429
|
+
if (pattern === "/" && pathname === "/") {
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
433
|
+
const patternSegments = pattern.split("/").filter(Boolean);
|
|
434
|
+
if (pattern !== "/") {
|
|
435
|
+
if (pathSegments.length !== patternSegments.length) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
439
|
+
if (patternSegments[i].startsWith(":")) {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
if (patternSegments[i] !== pathSegments[i]) {
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
return false;
|
|
449
|
+
};
|
|
450
|
+
var matchesPrefix = (pathname, pattern) => {
|
|
451
|
+
if (pattern === "/") return true;
|
|
452
|
+
const pathSegs = pathname.split("/").filter(Boolean);
|
|
453
|
+
const patSegs = pattern.split("/").filter(Boolean);
|
|
454
|
+
if (patSegs.length > pathSegs.length) return false;
|
|
455
|
+
for (let i = 0; i < patSegs.length; i++) {
|
|
456
|
+
const pat = patSegs[i];
|
|
457
|
+
const seg = pathSegs[i];
|
|
458
|
+
if (pat.startsWith(":")) continue;
|
|
459
|
+
if (pat !== seg) return false;
|
|
460
|
+
}
|
|
461
|
+
return true;
|
|
462
|
+
};
|
|
463
|
+
var normalizeSegments = (segments) => {
|
|
464
|
+
if (segments.length === 0) return segments;
|
|
465
|
+
const result = [];
|
|
466
|
+
for (const seg of segments) {
|
|
467
|
+
if (result.length === 0) {
|
|
468
|
+
result.push(seg);
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
const prev = result[result.length - 1];
|
|
472
|
+
const prevHref = typeof prev.href === "function" ? void 0 : prev.href;
|
|
473
|
+
const currHref = typeof seg.href === "function" ? void 0 : seg.href;
|
|
474
|
+
const isPrevHome = typeof prev.label === "string" && prev.label.trim().toLowerCase() === "home" && prevHref === "/";
|
|
475
|
+
const isCurrHome = typeof seg.label === "string" && seg.label.trim().toLowerCase() === "home" && currHref === "/";
|
|
476
|
+
if (isPrevHome && isCurrHome) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (prevHref && currHref && prevHref === currHref) {
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
result.push(seg);
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
485
|
+
};
|
|
486
|
+
var extractDynamicValues = (pathname, pattern) => {
|
|
487
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
488
|
+
const patternSegments = pattern.split("/").filter(Boolean);
|
|
489
|
+
const dynamicValues = {};
|
|
490
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
491
|
+
if (patternSegments[i].startsWith(":")) {
|
|
492
|
+
const key = patternSegments[i].slice(1);
|
|
493
|
+
if (i < pathSegments.length) {
|
|
494
|
+
dynamicValues[key] = pathSegments[i];
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return dynamicValues;
|
|
499
|
+
};
|
|
500
|
+
var resolveBreadcrumbLabel = async (label, supabase, pathname) => {
|
|
501
|
+
if (typeof label === "function") {
|
|
502
|
+
try {
|
|
503
|
+
if (supabase && pathname && label.length >= 2) {
|
|
504
|
+
return await label(supabase, pathname);
|
|
505
|
+
} else if (supabase && label.length >= 1) {
|
|
506
|
+
return await label(
|
|
507
|
+
supabase
|
|
508
|
+
);
|
|
509
|
+
} else {
|
|
510
|
+
return await label();
|
|
511
|
+
}
|
|
512
|
+
} catch (error) {
|
|
513
|
+
if (supabase) {
|
|
514
|
+
try {
|
|
515
|
+
return await label();
|
|
516
|
+
} catch (fallbackError) {
|
|
517
|
+
console.warn("Failed to resolve breadcrumb label:", fallbackError);
|
|
518
|
+
return "Error";
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
throw error;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return label;
|
|
525
|
+
};
|
|
526
|
+
var resolveBreadcrumbConfig = async (config, supabase, pathname) => {
|
|
527
|
+
const resolvedSegments = await Promise.all(
|
|
528
|
+
config.segments.map(async (segment) => {
|
|
529
|
+
const resolvedLabel = await resolveBreadcrumbLabel(
|
|
530
|
+
segment.label,
|
|
531
|
+
supabase,
|
|
532
|
+
pathname
|
|
533
|
+
);
|
|
534
|
+
let resolvedHref = segment.href;
|
|
535
|
+
if (typeof segment.href === "function" && pathname) {
|
|
536
|
+
try {
|
|
537
|
+
resolvedHref = segment.href(pathname);
|
|
538
|
+
} catch (error) {
|
|
539
|
+
console.warn("Error resolving href:", error);
|
|
540
|
+
resolvedHref = typeof segment.href === "string" ? segment.href : "#";
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
...segment,
|
|
545
|
+
label: resolvedLabel,
|
|
546
|
+
href: resolvedHref
|
|
547
|
+
};
|
|
548
|
+
})
|
|
549
|
+
);
|
|
550
|
+
return {
|
|
551
|
+
...config,
|
|
552
|
+
segments: resolvedSegments
|
|
553
|
+
};
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// src/nav/aceternity/useBreadcrumbs.ts
|
|
557
|
+
import { useCallback, useEffect, useState as useState2 } from "react";
|
|
558
|
+
var useBreadcrumbs = ({
|
|
559
|
+
pathname,
|
|
560
|
+
supabase,
|
|
561
|
+
autoResolve = true
|
|
562
|
+
}) => {
|
|
563
|
+
const [breadcrumbs, setBreadcrumbs] = useState2([]);
|
|
564
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
565
|
+
const [error, setError] = useState2(null);
|
|
566
|
+
const [rawConfig, setRawConfig] = useState2(null);
|
|
567
|
+
const generateBreadcrumbs = useCallback(async () => {
|
|
568
|
+
setIsLoading(true);
|
|
569
|
+
setError(null);
|
|
570
|
+
try {
|
|
571
|
+
const breadcrumbConfig = findBreadcrumbConfig(pathname);
|
|
572
|
+
if (!breadcrumbConfig) {
|
|
573
|
+
setBreadcrumbs([]);
|
|
574
|
+
setRawConfig(null);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
setRawConfig(breadcrumbConfig);
|
|
578
|
+
if (!autoResolve) {
|
|
579
|
+
const rawBreadcrumbs = breadcrumbConfig.segments.map((segment) => ({
|
|
580
|
+
label: typeof segment.label === "string" ? segment.label : "Loading...",
|
|
581
|
+
href: typeof segment.href === "function" && pathname ? segment.href(pathname) : segment.href,
|
|
582
|
+
icon: segment.icon
|
|
583
|
+
}));
|
|
584
|
+
setBreadcrumbs(rawBreadcrumbs);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
const resolvedConfig = await resolveBreadcrumbConfig(
|
|
588
|
+
breadcrumbConfig,
|
|
589
|
+
supabase,
|
|
590
|
+
pathname
|
|
591
|
+
);
|
|
592
|
+
const resolvedBreadcrumbs = resolvedConfig.segments.map((segment) => ({
|
|
593
|
+
label: typeof segment.label === "string" ? segment.label : "Loading...",
|
|
594
|
+
href: segment.href,
|
|
595
|
+
icon: segment.icon
|
|
596
|
+
}));
|
|
597
|
+
setBreadcrumbs(resolvedBreadcrumbs);
|
|
598
|
+
} catch (err) {
|
|
599
|
+
const errorMessage = err instanceof Error ? err.message : "Unknown error";
|
|
600
|
+
setError(errorMessage);
|
|
601
|
+
console.error("Error generating breadcrumbs:", err);
|
|
602
|
+
setBreadcrumbs([]);
|
|
603
|
+
} finally {
|
|
604
|
+
setIsLoading(false);
|
|
605
|
+
}
|
|
606
|
+
}, [pathname, supabase, autoResolve]);
|
|
607
|
+
const refresh = useCallback(async () => {
|
|
608
|
+
await generateBreadcrumbs();
|
|
609
|
+
}, [generateBreadcrumbs]);
|
|
610
|
+
useEffect(() => {
|
|
611
|
+
generateBreadcrumbs();
|
|
612
|
+
}, [generateBreadcrumbs]);
|
|
613
|
+
return {
|
|
614
|
+
breadcrumbs,
|
|
615
|
+
isLoading,
|
|
616
|
+
error,
|
|
617
|
+
refresh,
|
|
618
|
+
rawConfig
|
|
619
|
+
};
|
|
620
|
+
};
|
|
621
|
+
var usePageHeaderBreadcrumbs = (pathname, supabase) => {
|
|
622
|
+
const { breadcrumbs, isLoading, error } = useBreadcrumbs({
|
|
623
|
+
pathname,
|
|
624
|
+
supabase,
|
|
625
|
+
autoResolve: true
|
|
626
|
+
});
|
|
627
|
+
const customBreadcrumbs = breadcrumbs.map((item) => ({
|
|
628
|
+
label: item.label,
|
|
629
|
+
href: item.href,
|
|
630
|
+
icon: item.icon
|
|
631
|
+
}));
|
|
632
|
+
return {
|
|
633
|
+
customBreadcrumbs,
|
|
634
|
+
showBreadcrumbs: true,
|
|
635
|
+
isLoading,
|
|
636
|
+
error
|
|
637
|
+
};
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// src/nav/aceternity/usePageHeader.ts
|
|
641
|
+
import { useEffect as useEffect2 } from "react";
|
|
642
|
+
|
|
643
|
+
// src/nav/aceternity/BreadcrumbContext.tsx
|
|
644
|
+
import { createContext, useContext } from "react";
|
|
645
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
646
|
+
var BreadcrumbContext = createContext(
|
|
647
|
+
void 0
|
|
648
|
+
);
|
|
649
|
+
var useBreadcrumbContext = () => {
|
|
650
|
+
const context = useContext(BreadcrumbContext);
|
|
651
|
+
if (!context) {
|
|
652
|
+
throw new Error(
|
|
653
|
+
"useBreadcrumbContext must be used within a BreadcrumbProvider"
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
return context;
|
|
657
|
+
};
|
|
658
|
+
var BreadcrumbProvider = ({
|
|
659
|
+
children,
|
|
660
|
+
value
|
|
661
|
+
}) => {
|
|
662
|
+
return /* @__PURE__ */ jsx8(BreadcrumbContext.Provider, { value, children });
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
// src/nav/aceternity/usePageHeader.ts
|
|
666
|
+
var usePageHeader = (options) => {
|
|
667
|
+
const {
|
|
668
|
+
setPageTitle,
|
|
669
|
+
setPageSubtitle,
|
|
670
|
+
setCustomBreadcrumbs,
|
|
671
|
+
setBreadcrumbsVisibility,
|
|
672
|
+
clearCustomBreadcrumbs,
|
|
673
|
+
resetBreadcrumbs
|
|
674
|
+
} = useBreadcrumbContext();
|
|
675
|
+
useEffect2(() => {
|
|
676
|
+
if (options.title !== void 0) {
|
|
677
|
+
setPageTitle(options.title);
|
|
678
|
+
}
|
|
679
|
+
if (options.subtitle !== void 0) {
|
|
680
|
+
setPageSubtitle(options.subtitle);
|
|
681
|
+
}
|
|
682
|
+
if (options.customBreadcrumbs !== void 0) {
|
|
683
|
+
setCustomBreadcrumbs(options.customBreadcrumbs);
|
|
684
|
+
}
|
|
685
|
+
if (options.showBreadcrumbs !== void 0) {
|
|
686
|
+
setBreadcrumbsVisibility(options.showBreadcrumbs);
|
|
687
|
+
}
|
|
688
|
+
return () => {
|
|
689
|
+
if (options.customBreadcrumbs !== void 0) {
|
|
690
|
+
clearCustomBreadcrumbs();
|
|
691
|
+
}
|
|
692
|
+
if (options.title !== void 0 || options.subtitle !== void 0) {
|
|
693
|
+
resetBreadcrumbs();
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
}, [
|
|
697
|
+
options.title,
|
|
698
|
+
options.subtitle,
|
|
699
|
+
options.customBreadcrumbs,
|
|
700
|
+
options.showBreadcrumbs,
|
|
701
|
+
setPageTitle,
|
|
702
|
+
setPageSubtitle,
|
|
703
|
+
setCustomBreadcrumbs,
|
|
704
|
+
setBreadcrumbsVisibility,
|
|
705
|
+
clearCustomBreadcrumbs,
|
|
706
|
+
resetBreadcrumbs
|
|
707
|
+
]);
|
|
708
|
+
return {
|
|
709
|
+
setPageTitle,
|
|
710
|
+
setPageSubtitle,
|
|
711
|
+
setCustomBreadcrumbs,
|
|
712
|
+
setBreadcrumbsVisibility,
|
|
713
|
+
clearCustomBreadcrumbs,
|
|
714
|
+
resetBreadcrumbs
|
|
715
|
+
};
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
// src/nav/aceternity/PageHeader.tsx
|
|
719
|
+
import { cn as cn6 } from "@pol-studios/utils";
|
|
720
|
+
|
|
721
|
+
// src/nav/aceternity/Breadcrumbs.tsx
|
|
722
|
+
import React3, { useEffect as useEffect3, useState as useState3 } from "react";
|
|
723
|
+
import { Link } from "@tanstack/react-router";
|
|
724
|
+
import { cn as cn5 } from "@pol-studios/utils";
|
|
725
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
726
|
+
var Breadcrumbs = ({
|
|
727
|
+
config,
|
|
728
|
+
customSegments,
|
|
729
|
+
pathname,
|
|
730
|
+
className,
|
|
731
|
+
showHome = true
|
|
732
|
+
}) => {
|
|
733
|
+
const [resolvedSegments, setResolvedSegments] = useState3([]);
|
|
734
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
735
|
+
useEffect3(() => {
|
|
736
|
+
const processSegments = async () => {
|
|
737
|
+
setIsLoading(true);
|
|
738
|
+
const segments = customSegments || config?.segments || [];
|
|
739
|
+
const processedSegments = await Promise.all(
|
|
740
|
+
segments.map(async (segment) => {
|
|
741
|
+
const resolvedLabel = await resolveBreadcrumbLabel(segment.label);
|
|
742
|
+
return {
|
|
743
|
+
...segment,
|
|
744
|
+
label: resolvedLabel,
|
|
745
|
+
resolvedLabel
|
|
746
|
+
};
|
|
747
|
+
})
|
|
748
|
+
);
|
|
749
|
+
setResolvedSegments(processedSegments);
|
|
750
|
+
setIsLoading(false);
|
|
751
|
+
};
|
|
752
|
+
processSegments();
|
|
753
|
+
}, [config, customSegments, pathname]);
|
|
754
|
+
if (isLoading) {
|
|
755
|
+
return /* @__PURE__ */ jsx9(
|
|
756
|
+
"nav",
|
|
757
|
+
{
|
|
758
|
+
className: cn5(
|
|
759
|
+
"flex items-center space-x-1 text-sm text-muted-600",
|
|
760
|
+
className
|
|
761
|
+
),
|
|
762
|
+
children: /* @__PURE__ */ jsx9("div", { className: "animate-pulse bg-muted-200 h-4 w-24 rounded" })
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
if (!config && !customSegments) {
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
const displaySegments = showHome ? resolvedSegments : resolvedSegments.filter((segment) => segment.href !== "/");
|
|
770
|
+
if (displaySegments.length === 0) {
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
return /* @__PURE__ */ jsx9(
|
|
774
|
+
"nav",
|
|
775
|
+
{
|
|
776
|
+
className: cn5(
|
|
777
|
+
"flex items-center gap-2 text-sm",
|
|
778
|
+
className
|
|
779
|
+
),
|
|
780
|
+
"aria-label": "Breadcrumb navigation",
|
|
781
|
+
children: displaySegments.map((segment, index) => {
|
|
782
|
+
const isLast = index === displaySegments.length - 1;
|
|
783
|
+
const isClickable = segment.href && !isLast;
|
|
784
|
+
return /* @__PURE__ */ jsxs4(React3.Fragment, { children: [
|
|
785
|
+
index > 0 && /* @__PURE__ */ jsx9("span", { className: "text-muted-400", children: "/" }),
|
|
786
|
+
isClickable ? /* @__PURE__ */ jsx9(
|
|
787
|
+
Link,
|
|
788
|
+
{
|
|
789
|
+
to: segment.href,
|
|
790
|
+
className: cn5(
|
|
791
|
+
"transition-colors duration-200",
|
|
792
|
+
"hover:text-muted-900",
|
|
793
|
+
"text-muted-600"
|
|
794
|
+
),
|
|
795
|
+
"aria-label": `Navigate to ${segment.label}`,
|
|
796
|
+
children: segment.resolvedLabel
|
|
797
|
+
}
|
|
798
|
+
) : /* @__PURE__ */ jsx9(
|
|
799
|
+
"span",
|
|
800
|
+
{
|
|
801
|
+
className: cn5(
|
|
802
|
+
isLast ? "text-muted-900 font-medium" : "text-muted-600"
|
|
803
|
+
),
|
|
804
|
+
"aria-current": isLast ? "page" : void 0,
|
|
805
|
+
children: segment.resolvedLabel
|
|
806
|
+
}
|
|
807
|
+
)
|
|
808
|
+
] }, `${segment.label}-${index}`);
|
|
809
|
+
})
|
|
810
|
+
}
|
|
811
|
+
);
|
|
812
|
+
};
|
|
813
|
+
var Breadcrumbs_default = Breadcrumbs;
|
|
814
|
+
|
|
815
|
+
// src/nav/aceternity/PageHeader.tsx
|
|
816
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
817
|
+
var PageHeader = ({
|
|
818
|
+
title,
|
|
819
|
+
subtitle,
|
|
820
|
+
breadcrumbs,
|
|
821
|
+
showBreadcrumbs = true,
|
|
822
|
+
className,
|
|
823
|
+
children,
|
|
824
|
+
actions
|
|
825
|
+
}) => {
|
|
826
|
+
return /* @__PURE__ */ jsx10(
|
|
827
|
+
"div",
|
|
828
|
+
{
|
|
829
|
+
className: cn6(
|
|
830
|
+
"sticky top-0 h-[40px] z-40 bg-muted-100 backdrop-blur-xl box-border border-b border-muted-200",
|
|
831
|
+
className
|
|
832
|
+
),
|
|
833
|
+
children: /* @__PURE__ */ jsx10("div", { className: "px-4 py-1 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
|
|
834
|
+
/* @__PURE__ */ jsx10("div", { className: "flex-1", children: showBreadcrumbs && /* @__PURE__ */ jsx10(Breadcrumbs, { customSegments: breadcrumbs }) }),
|
|
835
|
+
actions && /* @__PURE__ */ jsx10("div", { className: "ml-4 flex items-center gap-2", children: actions })
|
|
836
|
+
] }) })
|
|
837
|
+
}
|
|
838
|
+
);
|
|
839
|
+
};
|
|
840
|
+
var PageHeader_default = PageHeader;
|
|
841
|
+
|
|
842
|
+
// src/nav/aceternity/side-bar-2.tsx
|
|
843
|
+
import { useState as useState5, createContext as createContext3, useContext as useContext3 } from "react";
|
|
844
|
+
import { AnimatePresence as AnimatePresence2, motion as motion3 } from "framer-motion";
|
|
845
|
+
import { cn as cn8 } from "@pol-studios/utils";
|
|
846
|
+
import { Link as Link2, useLocation } from "@tanstack/react-router";
|
|
847
|
+
import { ChevronLeft, ChevronRight, PanelRight } from "lucide-react";
|
|
848
|
+
|
|
849
|
+
// src/animate-primitives/primitives/radix/tooltip.tsx
|
|
850
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
851
|
+
import {
|
|
852
|
+
AnimatePresence,
|
|
853
|
+
motion as motion2,
|
|
854
|
+
useMotionValue,
|
|
855
|
+
useSpring
|
|
856
|
+
} from "motion/react";
|
|
857
|
+
|
|
858
|
+
// src/lib/get-strict-context.tsx
|
|
859
|
+
import * as React4 from "react";
|
|
860
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
861
|
+
function getStrictContext(name) {
|
|
862
|
+
const Context = React4.createContext(null);
|
|
863
|
+
Context.displayName = name;
|
|
864
|
+
function Provider({ value, children }) {
|
|
865
|
+
return /* @__PURE__ */ jsx11(Context.Provider, { value, children });
|
|
866
|
+
}
|
|
867
|
+
function useContext4() {
|
|
868
|
+
const context = React4.useContext(Context);
|
|
869
|
+
if (context === null) {
|
|
870
|
+
throw new Error(`${name} must be used within its provider`);
|
|
871
|
+
}
|
|
872
|
+
return context;
|
|
873
|
+
}
|
|
874
|
+
return [Provider, useContext4];
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// src/hooks/use-controlled-state.tsx
|
|
878
|
+
import * as React5 from "react";
|
|
879
|
+
function useControlledState(props) {
|
|
880
|
+
const { value, defaultValue, onChange } = props;
|
|
881
|
+
const [state, setInternalState] = React5.useState(
|
|
882
|
+
value !== void 0 ? value : defaultValue
|
|
883
|
+
);
|
|
884
|
+
React5.useEffect(() => {
|
|
885
|
+
if (value !== void 0) setInternalState(value);
|
|
886
|
+
}, [value]);
|
|
887
|
+
const setState = React5.useCallback(
|
|
888
|
+
(next, ...args) => {
|
|
889
|
+
setInternalState(next);
|
|
890
|
+
onChange?.(next, ...args);
|
|
891
|
+
},
|
|
892
|
+
[onChange]
|
|
893
|
+
);
|
|
894
|
+
return [state, setState];
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// src/animate-primitives/primitives/radix/tooltip.tsx
|
|
898
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
899
|
+
var [LocalTooltipProvider, useTooltip] = getStrictContext("TooltipContext");
|
|
900
|
+
function TooltipProvider(props) {
|
|
901
|
+
return /* @__PURE__ */ jsx12(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", ...props });
|
|
902
|
+
}
|
|
903
|
+
function Tooltip2({
|
|
904
|
+
followCursor = false,
|
|
905
|
+
followCursorSpringOptions = { stiffness: 200, damping: 17 },
|
|
906
|
+
...props
|
|
907
|
+
}) {
|
|
908
|
+
const [isOpen, setIsOpen] = useControlledState({
|
|
909
|
+
value: props?.open,
|
|
910
|
+
defaultValue: props?.defaultOpen,
|
|
911
|
+
onChange: props?.onOpenChange
|
|
912
|
+
});
|
|
913
|
+
const x = useMotionValue(0);
|
|
914
|
+
const y = useMotionValue(0);
|
|
915
|
+
return /* @__PURE__ */ jsx12(
|
|
916
|
+
LocalTooltipProvider,
|
|
917
|
+
{
|
|
918
|
+
value: {
|
|
919
|
+
isOpen,
|
|
920
|
+
setIsOpen,
|
|
921
|
+
x,
|
|
922
|
+
y,
|
|
923
|
+
followCursor,
|
|
924
|
+
followCursorSpringOptions
|
|
925
|
+
},
|
|
926
|
+
children: /* @__PURE__ */ jsx12(
|
|
927
|
+
TooltipPrimitive.Root,
|
|
928
|
+
{
|
|
929
|
+
"data-slot": "tooltip",
|
|
930
|
+
...props,
|
|
931
|
+
onOpenChange: setIsOpen
|
|
932
|
+
}
|
|
933
|
+
)
|
|
934
|
+
}
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
function TooltipTrigger({ onMouseMove, ...props }) {
|
|
938
|
+
const { x, y, followCursor } = useTooltip();
|
|
939
|
+
const handleMouseMove = (event) => {
|
|
940
|
+
onMouseMove?.(event);
|
|
941
|
+
const target = event.currentTarget.getBoundingClientRect();
|
|
942
|
+
if (followCursor === "x" || followCursor === true) {
|
|
943
|
+
const eventOffsetX = event.clientX - target.left;
|
|
944
|
+
const offsetXFromCenter = (eventOffsetX - target.width / 2) / 2;
|
|
945
|
+
x.set(offsetXFromCenter);
|
|
946
|
+
}
|
|
947
|
+
if (followCursor === "y" || followCursor === true) {
|
|
948
|
+
const eventOffsetY = event.clientY - target.top;
|
|
949
|
+
const offsetYFromCenter = (eventOffsetY - target.height / 2) / 2;
|
|
950
|
+
y.set(offsetYFromCenter);
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
return /* @__PURE__ */ jsx12(
|
|
954
|
+
TooltipPrimitive.Trigger,
|
|
955
|
+
{
|
|
956
|
+
"data-slot": "tooltip-trigger",
|
|
957
|
+
onMouseMove: handleMouseMove,
|
|
958
|
+
...props
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
function TooltipPortal(props) {
|
|
963
|
+
const { isOpen } = useTooltip();
|
|
964
|
+
return /* @__PURE__ */ jsx12(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx12(
|
|
965
|
+
TooltipPrimitive.Portal,
|
|
966
|
+
{
|
|
967
|
+
forceMount: true,
|
|
968
|
+
"data-slot": "tooltip-portal",
|
|
969
|
+
...props
|
|
970
|
+
}
|
|
971
|
+
) });
|
|
972
|
+
}
|
|
973
|
+
function TooltipContent({
|
|
974
|
+
onEscapeKeyDown,
|
|
975
|
+
onPointerDownOutside,
|
|
976
|
+
side,
|
|
977
|
+
sideOffset,
|
|
978
|
+
align,
|
|
979
|
+
alignOffset,
|
|
980
|
+
avoidCollisions,
|
|
981
|
+
collisionBoundary,
|
|
982
|
+
collisionPadding,
|
|
983
|
+
arrowPadding,
|
|
984
|
+
sticky,
|
|
985
|
+
hideWhenDetached,
|
|
986
|
+
style,
|
|
987
|
+
transition = { type: "spring", stiffness: 300, damping: 25 },
|
|
988
|
+
...props
|
|
989
|
+
}) {
|
|
990
|
+
const { x, y, followCursor, followCursorSpringOptions } = useTooltip();
|
|
991
|
+
const translateX = useSpring(x, followCursorSpringOptions);
|
|
992
|
+
const translateY = useSpring(y, followCursorSpringOptions);
|
|
993
|
+
return /* @__PURE__ */ jsx12(
|
|
994
|
+
TooltipPrimitive.Content,
|
|
995
|
+
{
|
|
996
|
+
asChild: true,
|
|
997
|
+
forceMount: true,
|
|
998
|
+
align,
|
|
999
|
+
alignOffset,
|
|
1000
|
+
side,
|
|
1001
|
+
sideOffset,
|
|
1002
|
+
avoidCollisions,
|
|
1003
|
+
collisionBoundary,
|
|
1004
|
+
collisionPadding,
|
|
1005
|
+
arrowPadding,
|
|
1006
|
+
sticky,
|
|
1007
|
+
hideWhenDetached,
|
|
1008
|
+
onEscapeKeyDown,
|
|
1009
|
+
onPointerDownOutside,
|
|
1010
|
+
children: /* @__PURE__ */ jsx12(
|
|
1011
|
+
motion2.div,
|
|
1012
|
+
{
|
|
1013
|
+
"data-slot": "popover-content",
|
|
1014
|
+
initial: { opacity: 0, scale: 0.5 },
|
|
1015
|
+
animate: { opacity: 1, scale: 1 },
|
|
1016
|
+
exit: { opacity: 0, scale: 0.5 },
|
|
1017
|
+
transition,
|
|
1018
|
+
style: {
|
|
1019
|
+
x: followCursor === "x" || followCursor === true ? translateX : void 0,
|
|
1020
|
+
y: followCursor === "y" || followCursor === true ? translateY : void 0,
|
|
1021
|
+
...style
|
|
1022
|
+
},
|
|
1023
|
+
...props
|
|
1024
|
+
},
|
|
1025
|
+
"popover-content"
|
|
1026
|
+
)
|
|
1027
|
+
}
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
function TooltipArrow(props) {
|
|
1031
|
+
return /* @__PURE__ */ jsx12(TooltipPrimitive.Arrow, { "data-slot": "tooltip-arrow", ...props });
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// src/animate-primitives/components/radix/tooltip.tsx
|
|
1035
|
+
import { cn as cn7 } from "@pol-studios/utils/tailwind";
|
|
1036
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1037
|
+
function TooltipProvider2({
|
|
1038
|
+
delayDuration = 0,
|
|
1039
|
+
...props
|
|
1040
|
+
}) {
|
|
1041
|
+
return /* @__PURE__ */ jsx13(TooltipProvider, { delayDuration, ...props });
|
|
1042
|
+
}
|
|
1043
|
+
function Tooltip3({ delayDuration = 0, ...props }) {
|
|
1044
|
+
return /* @__PURE__ */ jsx13(TooltipProvider2, { delayDuration, children: /* @__PURE__ */ jsx13(Tooltip2, { ...props }) });
|
|
1045
|
+
}
|
|
1046
|
+
function TooltipTrigger2({ ...props }) {
|
|
1047
|
+
return /* @__PURE__ */ jsx13(TooltipTrigger, { ...props });
|
|
1048
|
+
}
|
|
1049
|
+
function TooltipContent2({
|
|
1050
|
+
className,
|
|
1051
|
+
sideOffset = 4,
|
|
1052
|
+
children,
|
|
1053
|
+
...props
|
|
1054
|
+
}) {
|
|
1055
|
+
return /* @__PURE__ */ jsx13(TooltipPortal, { children: /* @__PURE__ */ jsxs6(
|
|
1056
|
+
TooltipContent,
|
|
1057
|
+
{
|
|
1058
|
+
sideOffset,
|
|
1059
|
+
className: cn7(
|
|
1060
|
+
"bg-foreground text-background z-50 w-fit origin-[var(--radix-tooltip-content-transform-origin)] rounded-md px-3 py-1.5 text-xs text-balance animate-in fade-in-0 zoom-in-[0.98] data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[0.98]",
|
|
1061
|
+
className
|
|
1062
|
+
),
|
|
1063
|
+
...props,
|
|
1064
|
+
children: [
|
|
1065
|
+
children,
|
|
1066
|
+
/* @__PURE__ */ jsx13(TooltipArrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
|
|
1067
|
+
]
|
|
1068
|
+
}
|
|
1069
|
+
) });
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/nav/aceternity/sidebar.config.tsx
|
|
1073
|
+
import { Home, Contact, FolderGit2, BookImage, Database, Calendar, Receipt, WalletCards, History, MessageSquarePlus, Settings2, ArrowLeft } from "lucide-react";
|
|
1074
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1075
|
+
var defaultSidebarLinks = [
|
|
1076
|
+
{
|
|
1077
|
+
label: "Home",
|
|
1078
|
+
icon: /* @__PURE__ */ jsx14(Home, { className: "w-5 h-5" }),
|
|
1079
|
+
href: "/",
|
|
1080
|
+
section: "main"
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
label: "Clients",
|
|
1084
|
+
icon: /* @__PURE__ */ jsx14(Contact, { className: "w-5 h-5" }),
|
|
1085
|
+
href: "/clients",
|
|
1086
|
+
userAccess: "admin_project",
|
|
1087
|
+
section: "main"
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
label: "Projects",
|
|
1091
|
+
icon: /* @__PURE__ */ jsx14(FolderGit2, { className: "w-5 h-5" }),
|
|
1092
|
+
href: "/projects",
|
|
1093
|
+
userAccess: "admin_project",
|
|
1094
|
+
section: "main"
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
label: "Fixture Catalog",
|
|
1098
|
+
icon: /* @__PURE__ */ jsx14(BookImage, { className: "w-5 h-5" }),
|
|
1099
|
+
href: "/fixtures",
|
|
1100
|
+
userAccess: "fixture_catalog",
|
|
1101
|
+
section: "main"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
label: "Project Database",
|
|
1105
|
+
icon: /* @__PURE__ */ jsx14(Database, { className: "w-5 h-5" }),
|
|
1106
|
+
href: "/project-databases",
|
|
1107
|
+
userAccess: "project_database",
|
|
1108
|
+
section: "main"
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
label: "Timesheet",
|
|
1112
|
+
icon: /* @__PURE__ */ jsx14(Calendar, { className: "w-5 h-5" }),
|
|
1113
|
+
href: "/timesheet",
|
|
1114
|
+
userAccess: "timesheet",
|
|
1115
|
+
section: "main"
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
label: "Expense Reports",
|
|
1119
|
+
icon: /* @__PURE__ */ jsx14(Receipt, { className: "w-5 h-5" }),
|
|
1120
|
+
href: "/expense",
|
|
1121
|
+
userAccess: "expense_report",
|
|
1122
|
+
section: "main"
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
label: "Invoice",
|
|
1126
|
+
icon: /* @__PURE__ */ jsx14(WalletCards, { className: "w-5 h-5" }),
|
|
1127
|
+
href: "/invoices",
|
|
1128
|
+
userAccess: "invoicing",
|
|
1129
|
+
section: "main"
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
label: "Change Log",
|
|
1133
|
+
icon: /* @__PURE__ */ jsx14(History, { className: "w-5 h-5" }),
|
|
1134
|
+
href: "/changelog",
|
|
1135
|
+
section: "secondary"
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
label: "Support",
|
|
1139
|
+
icon: /* @__PURE__ */ jsx14(MessageSquarePlus, { className: "w-5 h-5" }),
|
|
1140
|
+
href: "/support/tickets",
|
|
1141
|
+
section: "secondary"
|
|
1142
|
+
},
|
|
1143
|
+
{
|
|
1144
|
+
label: "Admin",
|
|
1145
|
+
icon: /* @__PURE__ */ jsx14(Settings2, { className: "w-5 h-5" }),
|
|
1146
|
+
href: "/admin",
|
|
1147
|
+
userAccess: "admin",
|
|
1148
|
+
section: "secondary"
|
|
1149
|
+
},
|
|
1150
|
+
{
|
|
1151
|
+
label: "Log Out",
|
|
1152
|
+
icon: /* @__PURE__ */ jsx14(ArrowLeft, { className: "w-5 h-5" }),
|
|
1153
|
+
onClick: void 0,
|
|
1154
|
+
section: "auth"
|
|
1155
|
+
}
|
|
1156
|
+
];
|
|
1157
|
+
var sidebarLinks = [...defaultSidebarLinks];
|
|
1158
|
+
var setSidebarLinks = (links) => {
|
|
1159
|
+
sidebarLinks = links;
|
|
1160
|
+
};
|
|
1161
|
+
var addSidebarLinks = (links) => {
|
|
1162
|
+
sidebarLinks = [...sidebarLinks, ...links];
|
|
1163
|
+
};
|
|
1164
|
+
var resetSidebarLinks = () => {
|
|
1165
|
+
sidebarLinks = [...defaultSidebarLinks];
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1168
|
+
// src/nav/aceternity/side-bar-2.tsx
|
|
1169
|
+
import { Fragment, jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1170
|
+
var SidebarContext = createContext3(
|
|
1171
|
+
void 0
|
|
1172
|
+
);
|
|
1173
|
+
var useSidebar = () => {
|
|
1174
|
+
const context = useContext3(SidebarContext);
|
|
1175
|
+
if (!context) {
|
|
1176
|
+
throw new Error("useSidebar must be used within a SidebarProvider");
|
|
1177
|
+
}
|
|
1178
|
+
return context;
|
|
1179
|
+
};
|
|
1180
|
+
var SidebarProvider = ({
|
|
1181
|
+
children,
|
|
1182
|
+
open: openProp,
|
|
1183
|
+
setOpen: setOpenProp,
|
|
1184
|
+
animate = true
|
|
1185
|
+
}) => {
|
|
1186
|
+
const [openState, setOpenState] = useState5(false);
|
|
1187
|
+
const open = openProp !== void 0 ? openProp : openState;
|
|
1188
|
+
const setOpen = setOpenProp !== void 0 ? setOpenProp : setOpenState;
|
|
1189
|
+
return /* @__PURE__ */ jsx15(SidebarContext.Provider, { value: { open, setOpen, animate }, children });
|
|
1190
|
+
};
|
|
1191
|
+
var Sidebar = ({
|
|
1192
|
+
children,
|
|
1193
|
+
open,
|
|
1194
|
+
setOpen,
|
|
1195
|
+
animate
|
|
1196
|
+
}) => {
|
|
1197
|
+
return /* @__PURE__ */ jsx15(SidebarProvider, { open, setOpen, animate, children });
|
|
1198
|
+
};
|
|
1199
|
+
function SidebarLayout({
|
|
1200
|
+
className,
|
|
1201
|
+
children,
|
|
1202
|
+
links = sidebarLinks,
|
|
1203
|
+
onSignOut,
|
|
1204
|
+
loginRoute = "/login",
|
|
1205
|
+
profile,
|
|
1206
|
+
hasAccess = () => true,
|
|
1207
|
+
headerActions,
|
|
1208
|
+
supabase,
|
|
1209
|
+
userProfilePicture,
|
|
1210
|
+
notificationIcon
|
|
1211
|
+
}) {
|
|
1212
|
+
const location = useLocation();
|
|
1213
|
+
const mainLinks = links.filter((l) => l.section === "main");
|
|
1214
|
+
const secondaryLinks = links.filter((l) => l.section === "secondary");
|
|
1215
|
+
const authLinks = links.filter((l) => l.section === "auth");
|
|
1216
|
+
if (authLinks.length > 0 && onSignOut) {
|
|
1217
|
+
authLinks[0].onClick = () => onSignOut();
|
|
1218
|
+
}
|
|
1219
|
+
const [open, setOpen] = useState5(false);
|
|
1220
|
+
const { customBreadcrumbs, showBreadcrumbs, isLoading } = usePageHeaderBreadcrumbs(location.pathname, supabase);
|
|
1221
|
+
return /* @__PURE__ */ jsx15(
|
|
1222
|
+
"div",
|
|
1223
|
+
{
|
|
1224
|
+
className: cn8(
|
|
1225
|
+
"mx-auto flex w-full flex-1 flex-col overflow-hidden md:flex-row min-h-screen z-[100]",
|
|
1226
|
+
className
|
|
1227
|
+
),
|
|
1228
|
+
children: /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1229
|
+
/* @__PURE__ */ jsx15(Sidebar, { open, setOpen, children: /* @__PURE__ */ jsx15(SidebarBody, { className: "justify-between z-50 gap-5", children: /* @__PURE__ */ jsxs7(
|
|
1230
|
+
"aside",
|
|
1231
|
+
{
|
|
1232
|
+
"data-testId": "side-bar",
|
|
1233
|
+
className: "flex flex-1 gap-4 flex-col p-2 px-3 overflow-y-auto overflow-x-hidden",
|
|
1234
|
+
role: "navigation",
|
|
1235
|
+
"aria-label": "Main sidebar navigation",
|
|
1236
|
+
children: [
|
|
1237
|
+
/* @__PURE__ */ jsxs7(
|
|
1238
|
+
"section",
|
|
1239
|
+
{
|
|
1240
|
+
className: cn8(
|
|
1241
|
+
"flex items-center gap-2 py-4 px-2 transition-all",
|
|
1242
|
+
open ? "justify-between" : "justify-center flex-col gap-3"
|
|
1243
|
+
),
|
|
1244
|
+
"aria-label": "User profile and notifications",
|
|
1245
|
+
children: [
|
|
1246
|
+
/* @__PURE__ */ jsxs7(
|
|
1247
|
+
"div",
|
|
1248
|
+
{
|
|
1249
|
+
className: cn8(
|
|
1250
|
+
"flex items-center gap-2",
|
|
1251
|
+
open ? "" : "flex-col"
|
|
1252
|
+
),
|
|
1253
|
+
children: [
|
|
1254
|
+
userProfilePicture,
|
|
1255
|
+
open && profile && /* @__PURE__ */ jsxs7("div", { className: "flex flex-col ml-2", children: [
|
|
1256
|
+
/* @__PURE__ */ jsxs7("span", { className: "font-semibold text-base text-muted-900 ", children: [
|
|
1257
|
+
profile.firstName,
|
|
1258
|
+
" ",
|
|
1259
|
+
profile.lastName
|
|
1260
|
+
] }),
|
|
1261
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs text-muted-500 ", children: profile.email })
|
|
1262
|
+
] })
|
|
1263
|
+
]
|
|
1264
|
+
}
|
|
1265
|
+
),
|
|
1266
|
+
/* @__PURE__ */ jsx15(
|
|
1267
|
+
"div",
|
|
1268
|
+
{
|
|
1269
|
+
className: cn8(
|
|
1270
|
+
"flex items-center gap-2",
|
|
1271
|
+
open ? "" : "flex-col"
|
|
1272
|
+
),
|
|
1273
|
+
children: notificationIcon
|
|
1274
|
+
}
|
|
1275
|
+
)
|
|
1276
|
+
]
|
|
1277
|
+
}
|
|
1278
|
+
),
|
|
1279
|
+
/* @__PURE__ */ jsx15(
|
|
1280
|
+
"nav",
|
|
1281
|
+
{
|
|
1282
|
+
className: "flex flex-col gap-0.5 mt-2",
|
|
1283
|
+
"aria-label": "Sidebar controls",
|
|
1284
|
+
children: /* @__PURE__ */ jsx15(SidebarCollapseExpandButton, { open, setOpen })
|
|
1285
|
+
}
|
|
1286
|
+
),
|
|
1287
|
+
/* @__PURE__ */ jsx15(
|
|
1288
|
+
"nav",
|
|
1289
|
+
{
|
|
1290
|
+
className: "flex flex-col gap-0.5 mt-2",
|
|
1291
|
+
"aria-label": "Main navigation",
|
|
1292
|
+
children: mainLinks.map((link, idx) => /* @__PURE__ */ jsx15(
|
|
1293
|
+
SidebarLink,
|
|
1294
|
+
{
|
|
1295
|
+
link,
|
|
1296
|
+
activePath: location.pathname,
|
|
1297
|
+
sidebarOpen: open,
|
|
1298
|
+
hasAccess,
|
|
1299
|
+
tabIndex: 0
|
|
1300
|
+
},
|
|
1301
|
+
idx
|
|
1302
|
+
))
|
|
1303
|
+
}
|
|
1304
|
+
),
|
|
1305
|
+
/* @__PURE__ */ jsx15("div", { className: "my-4 h-px w-full bg-muted-200" }),
|
|
1306
|
+
/* @__PURE__ */ jsx15("nav", { className: "flex flex-col", "aria-label": "Secondary navigation", children: secondaryLinks.map((link, idx) => /* @__PURE__ */ jsx15(
|
|
1307
|
+
SidebarLink,
|
|
1308
|
+
{
|
|
1309
|
+
link,
|
|
1310
|
+
activePath: location.pathname,
|
|
1311
|
+
sidebarOpen: open,
|
|
1312
|
+
hasAccess,
|
|
1313
|
+
tabIndex: 0
|
|
1314
|
+
},
|
|
1315
|
+
idx
|
|
1316
|
+
)) }),
|
|
1317
|
+
/* @__PURE__ */ jsx15("div", { className: "my-4 h-px w-full bg-muted-200" }),
|
|
1318
|
+
/* @__PURE__ */ jsx15("nav", { className: "flex flex-col", "aria-label": "Auth navigation", children: authLinks.map((link, idx) => /* @__PURE__ */ jsx15(
|
|
1319
|
+
SidebarLink,
|
|
1320
|
+
{
|
|
1321
|
+
link,
|
|
1322
|
+
activePath: location.pathname,
|
|
1323
|
+
sidebarOpen: open,
|
|
1324
|
+
hasAccess,
|
|
1325
|
+
tabIndex: 0
|
|
1326
|
+
},
|
|
1327
|
+
idx
|
|
1328
|
+
)) })
|
|
1329
|
+
]
|
|
1330
|
+
}
|
|
1331
|
+
) }) }),
|
|
1332
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex-1 flex flex-col min-w-0", children: [
|
|
1333
|
+
/* @__PURE__ */ jsx15(
|
|
1334
|
+
PageHeader,
|
|
1335
|
+
{
|
|
1336
|
+
title: void 0,
|
|
1337
|
+
subtitle: void 0,
|
|
1338
|
+
breadcrumbs: (() => {
|
|
1339
|
+
const breadcrumbs = customBreadcrumbs || [];
|
|
1340
|
+
if (isLoading && breadcrumbs.length > 0) {
|
|
1341
|
+
return breadcrumbs.map((b) => ({
|
|
1342
|
+
...b,
|
|
1343
|
+
label: "Loading...",
|
|
1344
|
+
href: typeof b.href === "function" ? "#" : b.href
|
|
1345
|
+
}));
|
|
1346
|
+
}
|
|
1347
|
+
return breadcrumbs.map((b) => ({
|
|
1348
|
+
...b,
|
|
1349
|
+
href: typeof b.href === "function" ? "#" : b.href
|
|
1350
|
+
}));
|
|
1351
|
+
})(),
|
|
1352
|
+
showBreadcrumbs,
|
|
1353
|
+
actions: headerActions
|
|
1354
|
+
}
|
|
1355
|
+
),
|
|
1356
|
+
/* @__PURE__ */ jsx15("div", { className: "flex-1 overflow-auto", children })
|
|
1357
|
+
] })
|
|
1358
|
+
] })
|
|
1359
|
+
}
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
var SidebarBody = (props) => {
|
|
1363
|
+
return /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1364
|
+
/* @__PURE__ */ jsx15(DesktopSidebar, { ...props }),
|
|
1365
|
+
/* @__PURE__ */ jsx15(MobileSidebar, { ...props })
|
|
1366
|
+
] });
|
|
1367
|
+
};
|
|
1368
|
+
var DesktopSidebar = ({
|
|
1369
|
+
className,
|
|
1370
|
+
children,
|
|
1371
|
+
...props
|
|
1372
|
+
}) => {
|
|
1373
|
+
const { open, setOpen, animate } = useSidebar();
|
|
1374
|
+
return /* @__PURE__ */ jsx15(Fragment, { children: /* @__PURE__ */ jsx15(
|
|
1375
|
+
motion3.div,
|
|
1376
|
+
{
|
|
1377
|
+
className: cn8(
|
|
1378
|
+
"h-[100dvh] hidden md:flex md:flex-col w-[300px] shrink-0 bg-muted-100/85 drop-shadow-2xl md:drop-shadow-md sticky top-0 left-0 backdrop-blur-xl backdrop-saturate-150",
|
|
1379
|
+
className,
|
|
1380
|
+
open && "px-4 py-4 "
|
|
1381
|
+
),
|
|
1382
|
+
animate: {
|
|
1383
|
+
width: animate ? open ? "300px" : "75px" : "300px"
|
|
1384
|
+
},
|
|
1385
|
+
...props,
|
|
1386
|
+
children
|
|
1387
|
+
}
|
|
1388
|
+
) });
|
|
1389
|
+
};
|
|
1390
|
+
var MobileSidebar = ({
|
|
1391
|
+
className,
|
|
1392
|
+
children,
|
|
1393
|
+
...props
|
|
1394
|
+
}) => {
|
|
1395
|
+
const { open, setOpen } = useSidebar();
|
|
1396
|
+
return /* @__PURE__ */ jsx15(Fragment, { children: /* @__PURE__ */ jsxs7(
|
|
1397
|
+
"div",
|
|
1398
|
+
{
|
|
1399
|
+
className: cn8(
|
|
1400
|
+
"h-10 px-4 py-4 flex flex-row md:hidden items-center justify-between w-full z-[98] bg-muted-100/85"
|
|
1401
|
+
),
|
|
1402
|
+
...props,
|
|
1403
|
+
children: [
|
|
1404
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex z-20 w-full gap-2 justify-between", children: [
|
|
1405
|
+
/* @__PURE__ */ jsx15("div", { className: "font-semibold", children: "Menu" }),
|
|
1406
|
+
/* @__PURE__ */ jsx15(
|
|
1407
|
+
Button,
|
|
1408
|
+
{
|
|
1409
|
+
variant: "ghost",
|
|
1410
|
+
size: "icon",
|
|
1411
|
+
className: "ml-auto p-1 min-h-[unset] h-min my-auto",
|
|
1412
|
+
onClick: () => setOpen((p) => !p),
|
|
1413
|
+
children: /* @__PURE__ */ jsx15(PanelRight, { className: "w-5 h-5" })
|
|
1414
|
+
}
|
|
1415
|
+
)
|
|
1416
|
+
] }),
|
|
1417
|
+
/* @__PURE__ */ jsx15(AnimatePresence2, { children: open && /* @__PURE__ */ jsx15(
|
|
1418
|
+
motion3.div,
|
|
1419
|
+
{
|
|
1420
|
+
initial: { x: "100%", opacity: 1 },
|
|
1421
|
+
animate: { x: 0, opacity: 1 },
|
|
1422
|
+
exit: { x: "100%", opacity: 1 },
|
|
1423
|
+
transition: { duration: 0.3, ease: "easeInOut" },
|
|
1424
|
+
className: cn8(
|
|
1425
|
+
"fixed inset-y-0 right-0 w-80 z-[100] flex flex-col justify-between bg-muted-100/85 drop-shadow-2xl rounded-2xl border border-muted-200 backdrop-blur-xl backdrop-saturate-150",
|
|
1426
|
+
className
|
|
1427
|
+
),
|
|
1428
|
+
children
|
|
1429
|
+
}
|
|
1430
|
+
) })
|
|
1431
|
+
]
|
|
1432
|
+
}
|
|
1433
|
+
) });
|
|
1434
|
+
};
|
|
1435
|
+
var SidebarLink = ({
|
|
1436
|
+
link,
|
|
1437
|
+
className,
|
|
1438
|
+
activePath,
|
|
1439
|
+
sidebarOpen,
|
|
1440
|
+
tabIndex,
|
|
1441
|
+
hasAccess = () => true
|
|
1442
|
+
}) => {
|
|
1443
|
+
const { open, setOpen, animate } = useSidebar();
|
|
1444
|
+
const isActive = link.href === "/" ? activePath === "/" : activePath && link.href && activePath.startsWith(link.href);
|
|
1445
|
+
const canAccess = link.userAccess ? hasAccess(link.userAccess) : true;
|
|
1446
|
+
if (!canAccess) return null;
|
|
1447
|
+
const linkContent = /* @__PURE__ */ jsxs7(
|
|
1448
|
+
Link2,
|
|
1449
|
+
{
|
|
1450
|
+
to: link.href || "/",
|
|
1451
|
+
className: cn8(
|
|
1452
|
+
"flex items-center gap-3 w-full rounded-xl px-3 py-2 transition cursor-pointer group/sidebar relative focus:outline-none",
|
|
1453
|
+
isActive && (sidebarOpen ? "bg-muted-100 text-muted-900" : "bg-muted-100/80 text-muted-900"),
|
|
1454
|
+
className
|
|
1455
|
+
),
|
|
1456
|
+
onClick: (e) => {
|
|
1457
|
+
setOpen(false);
|
|
1458
|
+
link.onClick && link.onClick(e);
|
|
1459
|
+
},
|
|
1460
|
+
"aria-current": isActive ? "page" : void 0,
|
|
1461
|
+
"aria-label": link.label,
|
|
1462
|
+
tabIndex,
|
|
1463
|
+
children: [
|
|
1464
|
+
isActive && /* @__PURE__ */ jsx15(
|
|
1465
|
+
"span",
|
|
1466
|
+
{
|
|
1467
|
+
className: cn8(
|
|
1468
|
+
"absolute left-0 top-1/2 -translate-y-1/2 h-8 w-1 rounded bg-primary-400 shadow transition-all",
|
|
1469
|
+
sidebarOpen ? "opacity-100 left-1" : "opacity-80 left-1"
|
|
1470
|
+
)
|
|
1471
|
+
}
|
|
1472
|
+
),
|
|
1473
|
+
/* @__PURE__ */ jsx15("span", { className: "flex items-center justify-center", children: link.icon }),
|
|
1474
|
+
/* @__PURE__ */ jsx15(
|
|
1475
|
+
motion3.span,
|
|
1476
|
+
{
|
|
1477
|
+
animate: {
|
|
1478
|
+
display: animate ? open ? "inline-block" : "none" : "inline-block",
|
|
1479
|
+
opacity: animate ? open ? 1 : 0 : 1,
|
|
1480
|
+
width: animate ? open ? "auto" : 0 : "auto"
|
|
1481
|
+
},
|
|
1482
|
+
className: cn8(
|
|
1483
|
+
isActive ? "text-muted-900 font-semibold w-max text-sm group-hover/sidebar:translate-x-1 transition duration-150 whitespace-pre inline-block !p-0 !m-0" : "text-muted-700 w-max text-sm group-hover/sidebar:translate-x-1 transition duration-150 whitespace-pre inline-block !p-0 !m-0",
|
|
1484
|
+
sidebarOpen === false && "hidden"
|
|
1485
|
+
),
|
|
1486
|
+
children: link.label
|
|
1487
|
+
}
|
|
1488
|
+
)
|
|
1489
|
+
]
|
|
1490
|
+
}
|
|
1491
|
+
);
|
|
1492
|
+
if (!open) {
|
|
1493
|
+
return /* @__PURE__ */ jsx15(TooltipProvider2, { children: /* @__PURE__ */ jsxs7(Tooltip3, { children: [
|
|
1494
|
+
/* @__PURE__ */ jsx15(TooltipTrigger2, { asChild: true, children: linkContent }),
|
|
1495
|
+
/* @__PURE__ */ jsx15(TooltipContent2, { side: "right", children: link.label })
|
|
1496
|
+
] }) });
|
|
1497
|
+
}
|
|
1498
|
+
return linkContent;
|
|
1499
|
+
};
|
|
1500
|
+
var SidebarCollapseExpandButton = ({
|
|
1501
|
+
open,
|
|
1502
|
+
setOpen
|
|
1503
|
+
}) => /* @__PURE__ */ jsx15(
|
|
1504
|
+
Button,
|
|
1505
|
+
{
|
|
1506
|
+
variant: "ghost",
|
|
1507
|
+
size: "icon",
|
|
1508
|
+
className: cn8(
|
|
1509
|
+
"rounded-xl w-full flex items-center justify-center px-3 py-2 mb-1 border border-transparent bg-transparent hover:bg-muted-200 transition"
|
|
1510
|
+
),
|
|
1511
|
+
"aria-label": open ? "Collapse sidebar" : "Expand sidebar",
|
|
1512
|
+
onClick: () => setOpen((p) => !p),
|
|
1513
|
+
children: open ? /* @__PURE__ */ jsx15(ChevronLeft, { className: "w-5 h-5" }) : /* @__PURE__ */ jsx15(ChevronRight, { className: "w-5 h-5" })
|
|
1514
|
+
}
|
|
1515
|
+
);
|
|
1516
|
+
export {
|
|
1517
|
+
BottomNav,
|
|
1518
|
+
BreadcrumbProvider,
|
|
1519
|
+
Breadcrumbs_default as Breadcrumbs,
|
|
1520
|
+
DesktopSidebar,
|
|
1521
|
+
MenuToggle,
|
|
1522
|
+
MenuToggle_default as MenuToggleDefault,
|
|
1523
|
+
MobileSidebar,
|
|
1524
|
+
NavBarGroupItem,
|
|
1525
|
+
PageHeader_default as PageHeader,
|
|
1526
|
+
Sidebar,
|
|
1527
|
+
SidebarBody,
|
|
1528
|
+
SidebarCollapseExpandButton,
|
|
1529
|
+
SidebarLayout,
|
|
1530
|
+
SidebarLink,
|
|
1531
|
+
SidebarProvider,
|
|
1532
|
+
UserProfileName,
|
|
1533
|
+
UserProfilePicture,
|
|
1534
|
+
addBreadcrumbConfigs,
|
|
1535
|
+
addHierarchicalBreadcrumbConfigs,
|
|
1536
|
+
addSidebarLinks,
|
|
1537
|
+
buildInheritedBreadcrumbConfig,
|
|
1538
|
+
clearBreadcrumbConfigs,
|
|
1539
|
+
defaultSidebarLinks,
|
|
1540
|
+
extractDynamicValues,
|
|
1541
|
+
findBreadcrumbConfig,
|
|
1542
|
+
getBreadcrumbConfigs,
|
|
1543
|
+
getHierarchicalBreadcrumbConfigs,
|
|
1544
|
+
resetSidebarLinks,
|
|
1545
|
+
resolveBreadcrumbConfig,
|
|
1546
|
+
resolveBreadcrumbLabel,
|
|
1547
|
+
setBreadcrumbConfigs,
|
|
1548
|
+
setHierarchicalBreadcrumbConfigs,
|
|
1549
|
+
setSidebarLinks,
|
|
1550
|
+
sidebarLinks,
|
|
1551
|
+
useBreadcrumbContext,
|
|
1552
|
+
useBreadcrumbs,
|
|
1553
|
+
usePageHeader,
|
|
1554
|
+
usePageHeaderBreadcrumbs,
|
|
1555
|
+
useSidebar
|
|
1556
|
+
};
|