@underverse-ui/underverse 0.1.37 → 0.1.38
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/index.cjs +2414 -479
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +347 -1
- package/dist/index.d.ts +347 -1
- package/dist/index.js +2429 -504
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,12 +40,14 @@ __export(index_exports, {
|
|
|
40
40
|
Breadcrumb: () => Breadcrumb_default,
|
|
41
41
|
Button: () => Button_default,
|
|
42
42
|
ButtonLoading: () => ButtonLoading,
|
|
43
|
+
Calendar: () => Calendar2,
|
|
43
44
|
Card: () => Card_default,
|
|
44
45
|
Carousel: () => Carousel,
|
|
45
46
|
CategoryTreeSelect: () => CategoryTreeSelect,
|
|
46
47
|
Checkbox: () => Checkbox,
|
|
47
48
|
CircularProgress: () => CircularProgress,
|
|
48
49
|
ClientOnly: () => ClientOnly,
|
|
50
|
+
ColorPicker: () => ColorPicker,
|
|
49
51
|
Combobox: () => Combobox,
|
|
50
52
|
CompactPagination: () => CompactPagination,
|
|
51
53
|
DataTable: () => DataTable_default,
|
|
@@ -71,6 +73,8 @@ __export(index_exports, {
|
|
|
71
73
|
FormSubmitButton: () => FormSubmitButton,
|
|
72
74
|
GlobalLoading: () => GlobalLoading,
|
|
73
75
|
GradientBadge: () => GradientBadge,
|
|
76
|
+
Grid: () => Grid_default,
|
|
77
|
+
GridItem: () => GridItem,
|
|
74
78
|
ImageUpload: () => ImageUpload,
|
|
75
79
|
InlineLoading: () => InlineLoading,
|
|
76
80
|
Input: () => Input_default,
|
|
@@ -78,6 +82,8 @@ __export(index_exports, {
|
|
|
78
82
|
Label: () => Label,
|
|
79
83
|
LanguageSwitcher: () => LanguageSwitcherHeadless,
|
|
80
84
|
LanguageSwitcherHeadless: () => LanguageSwitcherHeadless,
|
|
85
|
+
List: () => List_default,
|
|
86
|
+
ListItem: () => ListItem,
|
|
81
87
|
LoadingBar: () => LoadingBar,
|
|
82
88
|
LoadingDots: () => LoadingDots,
|
|
83
89
|
LoadingProgress: () => LoadingProgress,
|
|
@@ -136,11 +142,15 @@ __export(index_exports, {
|
|
|
136
142
|
Textarea: () => Textarea_default,
|
|
137
143
|
ThemeToggle: () => ThemeToggleHeadless,
|
|
138
144
|
ThemeToggleHeadless: () => ThemeToggleHeadless,
|
|
145
|
+
TimePicker: () => TimePicker,
|
|
146
|
+
Timeline: () => Timeline_default,
|
|
147
|
+
TimelineItem: () => TimelineItem,
|
|
139
148
|
ToastProvider: () => Toast_default,
|
|
140
149
|
Tooltip: () => Tooltip,
|
|
141
150
|
VARIANT_STYLES_ALERT: () => VARIANT_STYLES_ALERT,
|
|
142
151
|
VARIANT_STYLES_BTN: () => VARIANT_STYLES_BTN,
|
|
143
152
|
VerticalTabs: () => VerticalTabs,
|
|
153
|
+
Watermark: () => Watermark_default,
|
|
144
154
|
cn: () => cn,
|
|
145
155
|
getUnderverseMessages: () => getUnderverseMessages,
|
|
146
156
|
underverseMessages: () => underverseMessages,
|
|
@@ -5158,7 +5168,7 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
|
|
|
5158
5168
|
document.removeEventListener("keydown", handleEscape);
|
|
5159
5169
|
};
|
|
5160
5170
|
}, [isOpen]);
|
|
5161
|
-
const
|
|
5171
|
+
const isSameDay2 = (a, b) => {
|
|
5162
5172
|
if (!a || !b) return false;
|
|
5163
5173
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
5164
5174
|
};
|
|
@@ -5187,24 +5197,24 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
|
|
|
5187
5197
|
for (let i = 0; i < firstDay; i++) nodes.push(/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-8 h-8" }, `e-${i}`));
|
|
5188
5198
|
for (let d = 1; d <= daysInMonth; d++) {
|
|
5189
5199
|
const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), d);
|
|
5190
|
-
const isSelectedStart =
|
|
5191
|
-
const isSelectedEnd =
|
|
5200
|
+
const isSelectedStart = isSameDay2(date, tempStart);
|
|
5201
|
+
const isSelectedEnd = isSameDay2(date, tempEnd);
|
|
5192
5202
|
const isHovering = hoveredDate && tempStart && !tempEnd;
|
|
5193
5203
|
let isInRange = false;
|
|
5194
5204
|
let isRangeStart = false;
|
|
5195
5205
|
let isRangeEnd = false;
|
|
5196
5206
|
if (tempStart && tempEnd) {
|
|
5197
|
-
if (
|
|
5198
|
-
if (
|
|
5207
|
+
if (isSameDay2(date, tempStart)) isRangeStart = true;
|
|
5208
|
+
if (isSameDay2(date, tempEnd)) isRangeEnd = true;
|
|
5199
5209
|
if (inRange(date, tempStart, tempEnd)) isInRange = true;
|
|
5200
5210
|
} else if (isHovering) {
|
|
5201
5211
|
if (hoveredDate > tempStart) {
|
|
5202
|
-
if (
|
|
5203
|
-
if (
|
|
5212
|
+
if (isSameDay2(date, tempStart)) isRangeStart = true;
|
|
5213
|
+
if (isSameDay2(date, hoveredDate)) isRangeEnd = true;
|
|
5204
5214
|
if (inRange(date, tempStart, hoveredDate)) isInRange = true;
|
|
5205
5215
|
} else {
|
|
5206
|
-
if (
|
|
5207
|
-
if (
|
|
5216
|
+
if (isSameDay2(date, hoveredDate)) isRangeStart = true;
|
|
5217
|
+
if (isSameDay2(date, tempStart)) isRangeEnd = true;
|
|
5208
5218
|
if (inRange(date, hoveredDate, tempStart)) isInRange = true;
|
|
5209
5219
|
}
|
|
5210
5220
|
}
|
|
@@ -5316,12 +5326,610 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
|
|
|
5316
5326
|
] });
|
|
5317
5327
|
};
|
|
5318
5328
|
|
|
5319
|
-
// ../../components/ui/
|
|
5329
|
+
// ../../components/ui/TimePicker.tsx
|
|
5320
5330
|
var React22 = __toESM(require("react"), 1);
|
|
5321
|
-
var import_react15 = require("react");
|
|
5322
|
-
var import_react_dom8 = require("react-dom");
|
|
5323
5331
|
var import_lucide_react15 = require("lucide-react");
|
|
5324
5332
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5333
|
+
var pad = (n) => n.toString().padStart(2, "0");
|
|
5334
|
+
function parseTime(input, fmt = "24", includeSeconds) {
|
|
5335
|
+
if (!input) return null;
|
|
5336
|
+
const s = input.trim().toUpperCase();
|
|
5337
|
+
const ampm = s.endsWith("AM") || s.endsWith("PM");
|
|
5338
|
+
const clean = s.replace(/\s*(AM|PM)\s*$/, "");
|
|
5339
|
+
const segs = clean.split(":");
|
|
5340
|
+
const h = Number(segs[0]);
|
|
5341
|
+
const m = Number(segs[1] ?? 0);
|
|
5342
|
+
const sec = Number(segs[2] ?? 0);
|
|
5343
|
+
if (Number.isNaN(h) || Number.isNaN(m) || Number.isNaN(sec)) return null;
|
|
5344
|
+
if (fmt === "12" || ampm) {
|
|
5345
|
+
const p = s.endsWith("PM") ? "PM" : "AM";
|
|
5346
|
+
return { h: Math.max(1, Math.min(12, h)), m: Math.max(0, Math.min(59, m)), s: Math.max(0, Math.min(59, sec)), p };
|
|
5347
|
+
}
|
|
5348
|
+
return { h: Math.max(0, Math.min(23, h)), m: Math.max(0, Math.min(59, m)), s: Math.max(0, Math.min(59, sec)) };
|
|
5349
|
+
}
|
|
5350
|
+
function formatTime2({ h, m, s, p }, fmt, includeSeconds) {
|
|
5351
|
+
if (fmt === "12") {
|
|
5352
|
+
const period = p || (h >= 12 ? "PM" : "AM");
|
|
5353
|
+
const hr12 = h % 12 === 0 ? 12 : h % 12;
|
|
5354
|
+
const base2 = `${pad(hr12)}:${pad(m)}`;
|
|
5355
|
+
return includeSeconds ? `${base2}:${pad(s)} ${period}` : `${base2} ${period}`;
|
|
5356
|
+
}
|
|
5357
|
+
const base = `${pad(h)}:${pad(m)}`;
|
|
5358
|
+
return includeSeconds ? `${base}:${pad(s)}` : base;
|
|
5359
|
+
}
|
|
5360
|
+
var PRESETS = {
|
|
5361
|
+
morning: { h: 9, m: 0, s: 0 },
|
|
5362
|
+
afternoon: { h: 14, m: 0, s: 0 },
|
|
5363
|
+
evening: { h: 18, m: 0, s: 0 },
|
|
5364
|
+
night: { h: 21, m: 0, s: 0 }
|
|
5365
|
+
};
|
|
5366
|
+
function TimePicker({
|
|
5367
|
+
value,
|
|
5368
|
+
defaultValue,
|
|
5369
|
+
onChange,
|
|
5370
|
+
placeholder = "Select time",
|
|
5371
|
+
disabled = false,
|
|
5372
|
+
size = "md",
|
|
5373
|
+
label,
|
|
5374
|
+
required,
|
|
5375
|
+
format = "24",
|
|
5376
|
+
includeSeconds = false,
|
|
5377
|
+
minuteStep = 5,
|
|
5378
|
+
secondStep = 5,
|
|
5379
|
+
clearable = true,
|
|
5380
|
+
variant = "default",
|
|
5381
|
+
showNow = false,
|
|
5382
|
+
showPresets = false,
|
|
5383
|
+
allowManualInput = false,
|
|
5384
|
+
className,
|
|
5385
|
+
...rest
|
|
5386
|
+
}) {
|
|
5387
|
+
const isControlled = value !== void 0;
|
|
5388
|
+
const now = /* @__PURE__ */ new Date();
|
|
5389
|
+
const initial = parseTime(isControlled ? value : defaultValue, format, includeSeconds) || (format === "12" ? { h: now.getHours() % 12 || 12, m: now.getMinutes(), s: now.getSeconds(), p: now.getHours() >= 12 ? "PM" : "AM" } : { h: now.getHours(), m: now.getMinutes(), s: now.getSeconds() });
|
|
5390
|
+
const [open, setOpen] = React22.useState(false);
|
|
5391
|
+
const [parts, setParts] = React22.useState(initial);
|
|
5392
|
+
const [manualInput, setManualInput] = React22.useState("");
|
|
5393
|
+
React22.useEffect(() => {
|
|
5394
|
+
if (isControlled) {
|
|
5395
|
+
const parsed = parseTime(value, format, includeSeconds);
|
|
5396
|
+
if (parsed) setParts(parsed);
|
|
5397
|
+
}
|
|
5398
|
+
}, [value, isControlled, format, includeSeconds]);
|
|
5399
|
+
const emit = (next) => {
|
|
5400
|
+
onChange?.(next ? formatTime2(next, format, includeSeconds) : void 0);
|
|
5401
|
+
};
|
|
5402
|
+
const setNow = () => {
|
|
5403
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
5404
|
+
const h = now2.getHours();
|
|
5405
|
+
const m = now2.getMinutes();
|
|
5406
|
+
const s = now2.getSeconds();
|
|
5407
|
+
let next;
|
|
5408
|
+
if (format === "12") {
|
|
5409
|
+
next = { h: h % 12 || 12, m, s, p: h >= 12 ? "PM" : "AM" };
|
|
5410
|
+
} else {
|
|
5411
|
+
next = { h, m, s };
|
|
5412
|
+
}
|
|
5413
|
+
setParts(next);
|
|
5414
|
+
emit(next);
|
|
5415
|
+
};
|
|
5416
|
+
const setPreset = (preset) => {
|
|
5417
|
+
const { h, m, s } = PRESETS[preset];
|
|
5418
|
+
let next;
|
|
5419
|
+
if (format === "12") {
|
|
5420
|
+
next = { h: h % 12 || 12, m, s, p: h >= 12 ? "PM" : "AM" };
|
|
5421
|
+
} else {
|
|
5422
|
+
next = { h, m, s };
|
|
5423
|
+
}
|
|
5424
|
+
setParts(next);
|
|
5425
|
+
emit(next);
|
|
5426
|
+
};
|
|
5427
|
+
const handleManualInput = (input) => {
|
|
5428
|
+
setManualInput(input);
|
|
5429
|
+
const parsed = parseTime(input, format, includeSeconds);
|
|
5430
|
+
if (parsed) {
|
|
5431
|
+
setParts(parsed);
|
|
5432
|
+
emit(parsed);
|
|
5433
|
+
}
|
|
5434
|
+
};
|
|
5435
|
+
const hours = format === "24" ? Array.from({ length: 24 }, (_, i) => i) : Array.from({ length: 12 }, (_, i) => i + 1);
|
|
5436
|
+
const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => Math.min(59, i * minuteStep));
|
|
5437
|
+
const seconds = Array.from({ length: Math.ceil(60 / secondStep) }, (_, i) => Math.min(59, i * secondStep));
|
|
5438
|
+
const sizeClasses2 = {
|
|
5439
|
+
sm: { label: "text-xs", height: "h-8", padding: "px-2.5 py-1.5", text: "text-xs", icon: "w-3.5 h-3.5" },
|
|
5440
|
+
md: { label: "text-sm", height: "h-10", padding: "px-3 py-2", text: "text-sm", icon: "w-4 h-4" },
|
|
5441
|
+
lg: { label: "text-base", height: "h-12", padding: "px-4 py-3", text: "text-base", icon: "w-5 h-5" }
|
|
5442
|
+
};
|
|
5443
|
+
const sz = sizeClasses2[size];
|
|
5444
|
+
const radiusClass = size === "sm" ? "rounded-md" : "rounded-lg";
|
|
5445
|
+
const display = formatTime2(parts, format, includeSeconds);
|
|
5446
|
+
const trigger = variant === "inline" ? null : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
5447
|
+
"button",
|
|
5448
|
+
{
|
|
5449
|
+
type: "button",
|
|
5450
|
+
disabled,
|
|
5451
|
+
className: cn(
|
|
5452
|
+
"flex w-full items-center justify-between border border-input bg-background",
|
|
5453
|
+
sz.height,
|
|
5454
|
+
sz.padding,
|
|
5455
|
+
sz.text,
|
|
5456
|
+
radiusClass,
|
|
5457
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
5458
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
5459
|
+
"hover:bg-accent/5 transition-colors",
|
|
5460
|
+
className
|
|
5461
|
+
),
|
|
5462
|
+
children: [
|
|
5463
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.Clock, { className: cn(sz.icon, "text-muted-foreground") }),
|
|
5465
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: cn("truncate", !value && !defaultValue && "text-muted-foreground"), children: value || defaultValue ? display : placeholder })
|
|
5466
|
+
] }),
|
|
5467
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: cn("ml-2 transition-transform", open && "rotate-180"), children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { className: sz.icon, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) }) })
|
|
5468
|
+
]
|
|
5469
|
+
}
|
|
5470
|
+
);
|
|
5471
|
+
const contentWidth = variant === "compact" ? 240 : variant === "inline" ? 320 : includeSeconds ? 340 : 300;
|
|
5472
|
+
const timePickerContent = /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "space-y-3", children: [
|
|
5473
|
+
allowManualInput && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5474
|
+
Input_default,
|
|
5475
|
+
{
|
|
5476
|
+
placeholder: format === "12" ? "02:30 PM" : "14:30",
|
|
5477
|
+
value: manualInput || display,
|
|
5478
|
+
onChange: (e) => handleManualInput(e.target.value),
|
|
5479
|
+
size: "sm",
|
|
5480
|
+
variant: "outlined"
|
|
5481
|
+
}
|
|
5482
|
+
) }),
|
|
5483
|
+
showPresets && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-2 gap-2", children: Object.keys(PRESETS).map((preset) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5484
|
+
"button",
|
|
5485
|
+
{
|
|
5486
|
+
type: "button",
|
|
5487
|
+
className: "px-2 py-1.5 text-xs rounded-md border border-border hover:bg-accent/10 capitalize transition-colors",
|
|
5488
|
+
onClick: () => setPreset(preset),
|
|
5489
|
+
children: preset
|
|
5490
|
+
},
|
|
5491
|
+
preset
|
|
5492
|
+
)) }),
|
|
5493
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-2", children: [
|
|
5494
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 min-w-[60px]", children: [
|
|
5495
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Hour" }),
|
|
5496
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "max-h-48 overflow-y-auto pr-1 space-y-1 scrollbar-thin", children: hours.map((h) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5497
|
+
"button",
|
|
5498
|
+
{
|
|
5499
|
+
type: "button",
|
|
5500
|
+
className: cn(
|
|
5501
|
+
"w-full text-center px-2 py-1.5 rounded-md hover:bg-accent transition-colors text-sm",
|
|
5502
|
+
(format === "24" && parts.h === h || format === "12" && (parts.h % 12 || 12) === (h % 12 || 12)) && "bg-primary text-primary-foreground font-semibold"
|
|
5503
|
+
),
|
|
5504
|
+
onClick: () => {
|
|
5505
|
+
const nextH = format === "24" ? h : (parts.p === "PM" ? h % 12 + 12 : h % 12) % 24;
|
|
5506
|
+
const next = { ...parts, h: format === "24" ? h : nextH === 0 && parts.p === "AM" ? 0 : nextH || (parts.p === "PM" ? 12 : 0) };
|
|
5507
|
+
setParts(next);
|
|
5508
|
+
emit(next);
|
|
5509
|
+
},
|
|
5510
|
+
children: pad(h)
|
|
5511
|
+
},
|
|
5512
|
+
h
|
|
5513
|
+
)) })
|
|
5514
|
+
] }),
|
|
5515
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 min-w-[60px]", children: [
|
|
5516
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Min" }),
|
|
5517
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "max-h-48 overflow-y-auto pr-1 space-y-1 scrollbar-thin", children: minutes.map((m) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5518
|
+
"button",
|
|
5519
|
+
{
|
|
5520
|
+
type: "button",
|
|
5521
|
+
className: cn(
|
|
5522
|
+
"w-full text-center px-2 py-1.5 rounded-md hover:bg-accent transition-colors text-sm",
|
|
5523
|
+
parts.m === m && "bg-primary text-primary-foreground font-semibold"
|
|
5524
|
+
),
|
|
5525
|
+
onClick: () => {
|
|
5526
|
+
const next = { ...parts, m };
|
|
5527
|
+
setParts(next);
|
|
5528
|
+
emit(next);
|
|
5529
|
+
},
|
|
5530
|
+
children: pad(m)
|
|
5531
|
+
},
|
|
5532
|
+
m
|
|
5533
|
+
)) })
|
|
5534
|
+
] }),
|
|
5535
|
+
includeSeconds && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 min-w-[60px]", children: [
|
|
5536
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Sec" }),
|
|
5537
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "max-h-48 overflow-y-auto pr-1 space-y-1 scrollbar-thin", children: seconds.map((s) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5538
|
+
"button",
|
|
5539
|
+
{
|
|
5540
|
+
type: "button",
|
|
5541
|
+
className: cn(
|
|
5542
|
+
"w-full text-center px-2 py-1.5 rounded-md hover:bg-accent transition-colors text-sm",
|
|
5543
|
+
parts.s === s && "bg-primary text-primary-foreground font-semibold"
|
|
5544
|
+
),
|
|
5545
|
+
onClick: () => {
|
|
5546
|
+
const next = { ...parts, s };
|
|
5547
|
+
setParts(next);
|
|
5548
|
+
emit(next);
|
|
5549
|
+
},
|
|
5550
|
+
children: pad(s)
|
|
5551
|
+
},
|
|
5552
|
+
s
|
|
5553
|
+
)) })
|
|
5554
|
+
] }),
|
|
5555
|
+
format === "12" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "w-20", children: [
|
|
5556
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Period" }),
|
|
5557
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex flex-col gap-1.5", children: ["AM", "PM"].map((p) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5558
|
+
"button",
|
|
5559
|
+
{
|
|
5560
|
+
type: "button",
|
|
5561
|
+
className: cn(
|
|
5562
|
+
"px-3 py-2 rounded-md hover:bg-accent transition-colors text-sm font-medium",
|
|
5563
|
+
parts.p === p && "bg-primary text-primary-foreground"
|
|
5564
|
+
),
|
|
5565
|
+
onClick: () => {
|
|
5566
|
+
const pVal = p;
|
|
5567
|
+
let hour = parts.h;
|
|
5568
|
+
if (pVal === "AM" && hour >= 12) hour -= 12;
|
|
5569
|
+
if (pVal === "PM" && hour < 12) hour += 12;
|
|
5570
|
+
const next = { ...parts, p: pVal, h: hour };
|
|
5571
|
+
setParts(next);
|
|
5572
|
+
emit(next);
|
|
5573
|
+
},
|
|
5574
|
+
children: p
|
|
5575
|
+
},
|
|
5576
|
+
p
|
|
5577
|
+
)) })
|
|
5578
|
+
] })
|
|
5579
|
+
] }),
|
|
5580
|
+
(showNow || clearable) && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between gap-2 pt-2 border-t border-border", children: [
|
|
5581
|
+
showNow && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
5582
|
+
"button",
|
|
5583
|
+
{
|
|
5584
|
+
type: "button",
|
|
5585
|
+
className: "px-3 py-1.5 text-xs rounded-md border border-border hover:bg-accent/10 transition-colors flex items-center gap-1.5",
|
|
5586
|
+
onClick: () => {
|
|
5587
|
+
setNow();
|
|
5588
|
+
if (variant === "compact") setOpen(false);
|
|
5589
|
+
},
|
|
5590
|
+
children: [
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.Clock, { className: "w-3 h-3" }),
|
|
5592
|
+
"Now"
|
|
5593
|
+
]
|
|
5594
|
+
}
|
|
5595
|
+
),
|
|
5596
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex-1" }),
|
|
5597
|
+
clearable && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
5598
|
+
"button",
|
|
5599
|
+
{
|
|
5600
|
+
type: "button",
|
|
5601
|
+
className: "px-3 py-1.5 text-xs rounded-md border border-border hover:bg-destructive/10 transition-colors flex items-center gap-1.5",
|
|
5602
|
+
onClick: () => {
|
|
5603
|
+
setParts(initial);
|
|
5604
|
+
emit(void 0);
|
|
5605
|
+
setOpen(false);
|
|
5606
|
+
},
|
|
5607
|
+
children: [
|
|
5608
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.X, { className: "w-3 h-3" }),
|
|
5609
|
+
"Clear"
|
|
5610
|
+
]
|
|
5611
|
+
}
|
|
5612
|
+
)
|
|
5613
|
+
] })
|
|
5614
|
+
] });
|
|
5615
|
+
if (variant === "inline") {
|
|
5616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "w-full", ...rest, children: [
|
|
5617
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: cn(sz.label, "font-medium", disabled ? "text-muted-foreground" : "text-foreground"), children: [
|
|
5618
|
+
label,
|
|
5619
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-destructive ml-1", children: "*" })
|
|
5620
|
+
] }) }),
|
|
5621
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("p-3 rounded-lg border border-border bg-card shadow-sm", className), children: timePickerContent })
|
|
5622
|
+
] });
|
|
5623
|
+
}
|
|
5624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "w-full", ...rest, children: [
|
|
5625
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex items-center justify-between mb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: cn(sz.label, "font-medium", disabled ? "text-muted-foreground" : "text-foreground"), onClick: () => !disabled && setOpen(true), children: [
|
|
5626
|
+
label,
|
|
5627
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-destructive ml-1", children: "*" })
|
|
5628
|
+
] }) }),
|
|
5629
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5630
|
+
Popover,
|
|
5631
|
+
{
|
|
5632
|
+
trigger,
|
|
5633
|
+
open,
|
|
5634
|
+
onOpenChange: (o) => setOpen(o),
|
|
5635
|
+
placement: "bottom-start",
|
|
5636
|
+
matchTriggerWidth: variant === "compact",
|
|
5637
|
+
contentWidth,
|
|
5638
|
+
contentClassName: cn("p-3 rounded-lg border border-border bg-popover shadow-lg backdrop-blur-sm bg-popover/95"),
|
|
5639
|
+
children: timePickerContent
|
|
5640
|
+
}
|
|
5641
|
+
)
|
|
5642
|
+
] });
|
|
5643
|
+
}
|
|
5644
|
+
|
|
5645
|
+
// ../../components/ui/Calendar.tsx
|
|
5646
|
+
var React23 = __toESM(require("react"), 1);
|
|
5647
|
+
var import_lucide_react16 = require("lucide-react");
|
|
5648
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5649
|
+
function startOfMonth(d) {
|
|
5650
|
+
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
5651
|
+
}
|
|
5652
|
+
function endOfMonth(d) {
|
|
5653
|
+
return new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
5654
|
+
}
|
|
5655
|
+
function addMonths(d, n) {
|
|
5656
|
+
const nd = new Date(d);
|
|
5657
|
+
nd.setMonth(d.getMonth() + n);
|
|
5658
|
+
return nd;
|
|
5659
|
+
}
|
|
5660
|
+
function isSameDay(a, b) {
|
|
5661
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
5662
|
+
}
|
|
5663
|
+
function toDate(x) {
|
|
5664
|
+
return x instanceof Date ? x : new Date(x);
|
|
5665
|
+
}
|
|
5666
|
+
function addDays(d, n) {
|
|
5667
|
+
const nd = new Date(d);
|
|
5668
|
+
nd.setDate(d.getDate() + n);
|
|
5669
|
+
return nd;
|
|
5670
|
+
}
|
|
5671
|
+
function startOfWeek(d, weekStartsOn) {
|
|
5672
|
+
const day = d.getDay();
|
|
5673
|
+
const diff = (day - weekStartsOn + 7) % 7;
|
|
5674
|
+
const s = new Date(d);
|
|
5675
|
+
s.setDate(d.getDate() - diff);
|
|
5676
|
+
return new Date(s.getFullYear(), s.getMonth(), s.getDate());
|
|
5677
|
+
}
|
|
5678
|
+
function getMonthGrid(view, weekStartsOn) {
|
|
5679
|
+
const start = startOfMonth(view);
|
|
5680
|
+
const end = endOfMonth(view);
|
|
5681
|
+
const startDay = (start.getDay() - weekStartsOn + 7) % 7;
|
|
5682
|
+
const days = [];
|
|
5683
|
+
for (let i = 0; i < startDay; i++) {
|
|
5684
|
+
const d = new Date(start);
|
|
5685
|
+
d.setDate(d.getDate() - (startDay - i));
|
|
5686
|
+
days.push(d);
|
|
5687
|
+
}
|
|
5688
|
+
for (let d = 1; d <= end.getDate(); d++) {
|
|
5689
|
+
days.push(new Date(view.getFullYear(), view.getMonth(), d));
|
|
5690
|
+
}
|
|
5691
|
+
while (days.length % 7 !== 0) {
|
|
5692
|
+
const last = days[days.length - 1];
|
|
5693
|
+
const next = new Date(last);
|
|
5694
|
+
next.setDate(last.getDate() + 1);
|
|
5695
|
+
days.push(next);
|
|
5696
|
+
}
|
|
5697
|
+
return days;
|
|
5698
|
+
}
|
|
5699
|
+
function Calendar2({
|
|
5700
|
+
month,
|
|
5701
|
+
defaultMonth,
|
|
5702
|
+
onMonthChange,
|
|
5703
|
+
value,
|
|
5704
|
+
defaultValue,
|
|
5705
|
+
onSelect,
|
|
5706
|
+
selectMode = "single",
|
|
5707
|
+
weekStartsOn = 0,
|
|
5708
|
+
showWeekdays = true,
|
|
5709
|
+
showHeader = true,
|
|
5710
|
+
size = "md",
|
|
5711
|
+
variant = "default",
|
|
5712
|
+
events = [],
|
|
5713
|
+
renderDay,
|
|
5714
|
+
labels,
|
|
5715
|
+
className,
|
|
5716
|
+
display = "month",
|
|
5717
|
+
months = 1,
|
|
5718
|
+
showToday = false,
|
|
5719
|
+
showClear = false,
|
|
5720
|
+
minDate,
|
|
5721
|
+
maxDate,
|
|
5722
|
+
disabledDates,
|
|
5723
|
+
dense = false,
|
|
5724
|
+
animate = false,
|
|
5725
|
+
showEventBadges = false,
|
|
5726
|
+
highlightWeekends = false,
|
|
5727
|
+
...rest
|
|
5728
|
+
}) {
|
|
5729
|
+
const isControlledMonth = month != null;
|
|
5730
|
+
const [view, setView] = React23.useState(() => month ?? defaultMonth ?? /* @__PURE__ */ new Date());
|
|
5731
|
+
React23.useEffect(() => {
|
|
5732
|
+
if (isControlledMonth && month) setView(month);
|
|
5733
|
+
}, [isControlledMonth, month]);
|
|
5734
|
+
const isControlledValue = value !== void 0;
|
|
5735
|
+
const [internal, setInternal] = React23.useState(defaultValue);
|
|
5736
|
+
const selected = isControlledValue ? value : internal;
|
|
5737
|
+
const goByView = (delta) => {
|
|
5738
|
+
const next = display === "week" ? addDays(view, delta * 7) : addMonths(view, delta);
|
|
5739
|
+
if (!isControlledMonth) setView(next);
|
|
5740
|
+
if (display === "month") onMonthChange?.(next);
|
|
5741
|
+
};
|
|
5742
|
+
const weekNames = labels?.weekdays ?? ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
5743
|
+
const rotate = (arr, n) => arr.slice(n).concat(arr.slice(0, n));
|
|
5744
|
+
const weekdays = rotate(weekNames, weekStartsOn);
|
|
5745
|
+
const days = getMonthGrid(view, weekStartsOn);
|
|
5746
|
+
const today = /* @__PURE__ */ new Date();
|
|
5747
|
+
const byDay = React23.useMemo(() => {
|
|
5748
|
+
const map = /* @__PURE__ */ new Map();
|
|
5749
|
+
for (const e of events) {
|
|
5750
|
+
const d = toDate(e.date);
|
|
5751
|
+
const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
5752
|
+
if (!map.has(k)) map.set(k, []);
|
|
5753
|
+
map.get(k).push(e);
|
|
5754
|
+
}
|
|
5755
|
+
return map;
|
|
5756
|
+
}, [events]);
|
|
5757
|
+
const isSelected = (d) => {
|
|
5758
|
+
if (!selected) return false;
|
|
5759
|
+
if (selectMode === "single" && selected instanceof Date) return isSameDay(selected, d);
|
|
5760
|
+
if (selectMode === "multiple" && Array.isArray(selected)) return selected.some((x) => isSameDay(x, d));
|
|
5761
|
+
if (selectMode === "range" && !Array.isArray(selected) && typeof selected === "object") {
|
|
5762
|
+
const s = selected.start;
|
|
5763
|
+
const e = selected.end;
|
|
5764
|
+
if (s && e) return d >= new Date(s.getFullYear(), s.getMonth(), s.getDate()) && d <= new Date(e.getFullYear(), e.getMonth(), e.getDate());
|
|
5765
|
+
if (s) return isSameDay(s, d);
|
|
5766
|
+
if (e) return isSameDay(e, d);
|
|
5767
|
+
}
|
|
5768
|
+
return false;
|
|
5769
|
+
};
|
|
5770
|
+
const commit = (next) => {
|
|
5771
|
+
if (!isControlledValue) setInternal(next);
|
|
5772
|
+
onSelect?.(next);
|
|
5773
|
+
};
|
|
5774
|
+
const handleClickDay = (d) => {
|
|
5775
|
+
if (selectMode === "single") {
|
|
5776
|
+
commit(d);
|
|
5777
|
+
return;
|
|
5778
|
+
}
|
|
5779
|
+
if (selectMode === "multiple") {
|
|
5780
|
+
const arr = Array.isArray(selected) ? selected : [];
|
|
5781
|
+
const exists = arr.some((x) => isSameDay(x, d));
|
|
5782
|
+
const next = exists ? arr.filter((x) => !isSameDay(x, d)) : [...arr, d];
|
|
5783
|
+
commit(next);
|
|
5784
|
+
return;
|
|
5785
|
+
}
|
|
5786
|
+
if (selectMode === "range") {
|
|
5787
|
+
const cur = !Array.isArray(selected) && typeof selected === "object" ? selected : {};
|
|
5788
|
+
const s = cur.start;
|
|
5789
|
+
const e = cur.end;
|
|
5790
|
+
if (!s || s && e) {
|
|
5791
|
+
commit({ start: d, end: void 0 });
|
|
5792
|
+
} else if (s && !e) {
|
|
5793
|
+
if (d < s) commit({ start: d, end: s });
|
|
5794
|
+
else commit({ start: s, end: d });
|
|
5795
|
+
}
|
|
5796
|
+
}
|
|
5797
|
+
};
|
|
5798
|
+
const isDateDisabled = React23.useCallback((d) => {
|
|
5799
|
+
if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
|
|
5800
|
+
if (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
|
|
5801
|
+
if (Array.isArray(disabledDates)) {
|
|
5802
|
+
return disabledDates.some((dd) => isSameDay(dd, d));
|
|
5803
|
+
}
|
|
5804
|
+
if (typeof disabledDates === "function") {
|
|
5805
|
+
return disabledDates(d);
|
|
5806
|
+
}
|
|
5807
|
+
return false;
|
|
5808
|
+
}, [minDate, maxDate, disabledDates]);
|
|
5809
|
+
const SIZE_STYLES3 = {
|
|
5810
|
+
sm: { day: "w-8 h-8 text-[12px]", grid: dense ? "gap-0.5" : "gap-1", head: "text-[11px]", header: "text-sm" },
|
|
5811
|
+
md: { day: "w-9 h-9 text-sm", grid: dense ? "gap-1" : "gap-1.5", head: "text-xs", header: "text-sm" },
|
|
5812
|
+
lg: { day: "w-11 h-11 text-base", grid: dense ? "gap-1.5" : "gap-2", head: "text-sm", header: "text-base" },
|
|
5813
|
+
xl: { day: "w-14 h-14 text-lg", grid: dense ? "gap-2" : "gap-2.5", head: "text-base", header: "text-lg" }
|
|
5814
|
+
};
|
|
5815
|
+
const sz = SIZE_STYLES3[size];
|
|
5816
|
+
const VARIANT_STYLES2 = {
|
|
5817
|
+
default: "border border-border rounded-lg bg-card",
|
|
5818
|
+
bordered: "border-2 border-border rounded-xl bg-card shadow-sm",
|
|
5819
|
+
card: "border border-border rounded-xl bg-card shadow-lg",
|
|
5820
|
+
minimal: "bg-transparent"
|
|
5821
|
+
};
|
|
5822
|
+
const weekDays = React23.useMemo(() => {
|
|
5823
|
+
const s = startOfWeek(view, weekStartsOn);
|
|
5824
|
+
return Array.from({ length: 7 }, (_, i) => addDays(s, i));
|
|
5825
|
+
}, [view, weekStartsOn]);
|
|
5826
|
+
const renderMonth = (monthDate) => {
|
|
5827
|
+
const monthDays = getMonthGrid(monthDate, weekStartsOn);
|
|
5828
|
+
const monthLabel = labels?.month ? labels.month(monthDate) : monthDate.toLocaleDateString("en-US", { month: "long", year: "numeric" });
|
|
5829
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
5830
|
+
months > 1 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex items-center justify-center mb-2 text-sm font-semibold", children: monthLabel }),
|
|
5831
|
+
showWeekdays && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn("grid grid-cols-7", sz.grid, "mb-1 text-center text-muted-foreground font-medium"), children: weekdays.map((w) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn(sz.head), children: w }, `${monthLabel}-${w}`)) }),
|
|
5832
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn("grid grid-cols-7", sz.grid), children: monthDays.map((d, idx) => {
|
|
5833
|
+
const inMonth = d.getMonth() === monthDate.getMonth();
|
|
5834
|
+
const isToday2 = isSameDay(d, today);
|
|
5835
|
+
const selectedDay = isSelected(d);
|
|
5836
|
+
const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
5837
|
+
const dayEvents = byDay.get(k) || [];
|
|
5838
|
+
const disabled = isDateDisabled(d);
|
|
5839
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5840
|
+
"button",
|
|
5841
|
+
{
|
|
5842
|
+
onClick: () => handleClickDay(d),
|
|
5843
|
+
disabled,
|
|
5844
|
+
className: cn(
|
|
5845
|
+
"rounded-md flex items-center justify-center relative",
|
|
5846
|
+
sz.day,
|
|
5847
|
+
!inMonth && "text-muted-foreground/60",
|
|
5848
|
+
disabled && "opacity-40 cursor-not-allowed",
|
|
5849
|
+
isToday2 && !selectedDay && "ring-1 ring-primary/50",
|
|
5850
|
+
selectedDay && "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
5851
|
+
!selectedDay && "hover:bg-accent"
|
|
5852
|
+
),
|
|
5853
|
+
title: d.toDateString(),
|
|
5854
|
+
children: [
|
|
5855
|
+
d.getDate(),
|
|
5856
|
+
dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, i)) })
|
|
5857
|
+
]
|
|
5858
|
+
},
|
|
5859
|
+
`${monthLabel}-${idx}`
|
|
5860
|
+
);
|
|
5861
|
+
}) })
|
|
5862
|
+
] });
|
|
5863
|
+
};
|
|
5864
|
+
const minBound = React23.useMemo(() => minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()) : void 0, [minDate]);
|
|
5865
|
+
const maxBound = React23.useMemo(() => maxDate ? new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()) : void 0, [maxDate]);
|
|
5866
|
+
const prevDisabled = React23.useMemo(() => {
|
|
5867
|
+
if (!minBound) return false;
|
|
5868
|
+
if (display === "week") {
|
|
5869
|
+
const start = startOfWeek(view, weekStartsOn);
|
|
5870
|
+
const prevEnd2 = addDays(start, -1);
|
|
5871
|
+
return prevEnd2 < minBound;
|
|
5872
|
+
}
|
|
5873
|
+
const prevEnd = endOfMonth(addMonths(view, -1));
|
|
5874
|
+
return prevEnd < minBound;
|
|
5875
|
+
}, [display, view, weekStartsOn, minBound]);
|
|
5876
|
+
const nextDisabled = React23.useMemo(() => {
|
|
5877
|
+
if (!maxBound) return false;
|
|
5878
|
+
if (display === "week") {
|
|
5879
|
+
const start = startOfWeek(view, weekStartsOn);
|
|
5880
|
+
const nextStart2 = addDays(start, 7);
|
|
5881
|
+
return nextStart2 > maxBound;
|
|
5882
|
+
}
|
|
5883
|
+
const nextStart = startOfMonth(addMonths(view, 1));
|
|
5884
|
+
return nextStart > maxBound;
|
|
5885
|
+
}, [display, view, weekStartsOn, maxBound]);
|
|
5886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("w-full", className), ...rest, children: [
|
|
5887
|
+
showHeader && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
|
|
5888
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { onClick: () => goByView(-1), disabled: prevDisabled, className: cn("p-1 rounded-md hover:bg-accent", prevDisabled && "opacity-40 cursor-not-allowed hover:bg-transparent"), "aria-label": labels?.prev || (display === "week" ? "Previous week" : "Previous month"), children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.ChevronLeft, { className: "h-4 w-4" }) }),
|
|
5889
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "text-sm font-semibold", children: display === "week" ? `${labels?.month ? labels.month(weekDays[0]) : weekDays[0].toLocaleDateString("en-US", { month: "short" })} ${weekDays[0].getDate()} \u2013 ${labels?.month ? labels.month(weekDays[6]) : weekDays[6].toLocaleDateString("en-US", { month: "short" })} ${weekDays[6].getDate()}` : labels?.month ? labels.month(view) : view.toLocaleDateString("en-US", { month: "long", year: "numeric" }) }),
|
|
5890
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { onClick: () => goByView(1), disabled: nextDisabled, className: cn("p-1 rounded-md hover:bg-accent", nextDisabled && "opacity-40 cursor-not-allowed hover:bg-transparent"), "aria-label": labels?.next || (display === "week" ? "Next week" : "Next month"), children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.ChevronRight, { className: "h-4 w-4" }) })
|
|
5891
|
+
] }),
|
|
5892
|
+
display === "week" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
5893
|
+
showWeekdays && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn("grid grid-cols-7", sz.grid, "mb-1 text-center text-muted-foreground font-medium"), children: weekdays.map((w) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn(sz.head), children: w }, `w-${w}`)) }),
|
|
5894
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn("grid grid-cols-7", sz.grid), children: weekDays.map((d, idx) => {
|
|
5895
|
+
const inMonth = true;
|
|
5896
|
+
const isToday2 = isSameDay(d, today);
|
|
5897
|
+
const selectedDay = isSelected(d);
|
|
5898
|
+
const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
5899
|
+
const dayEvents = byDay.get(k) || [];
|
|
5900
|
+
const disabled = isDateDisabled(d);
|
|
5901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5902
|
+
"button",
|
|
5903
|
+
{
|
|
5904
|
+
onClick: () => handleClickDay(d),
|
|
5905
|
+
disabled,
|
|
5906
|
+
className: cn(
|
|
5907
|
+
"rounded-md flex items-center justify-center relative",
|
|
5908
|
+
sz.day,
|
|
5909
|
+
disabled && "opacity-40 cursor-not-allowed",
|
|
5910
|
+
isToday2 && !selectedDay && "ring-1 ring-primary/50",
|
|
5911
|
+
selectedDay && "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
5912
|
+
!selectedDay && "hover:bg-accent"
|
|
5913
|
+
),
|
|
5914
|
+
title: d.toDateString(),
|
|
5915
|
+
children: [
|
|
5916
|
+
d.getDate(),
|
|
5917
|
+
dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, i)) })
|
|
5918
|
+
]
|
|
5919
|
+
},
|
|
5920
|
+
`wd-${idx}`
|
|
5921
|
+
);
|
|
5922
|
+
}) })
|
|
5923
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn(months > 1 ? "grid md:grid-cols-2 lg:grid-cols-3 gap-4" : ""), children: Array.from({ length: Math.max(1, months) }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(React23.Fragment, { children: renderMonth(addMonths(view, i)) }, `cal-month-${view.getFullYear()}-${view.getMonth()}-${i}`)) })
|
|
5924
|
+
] });
|
|
5925
|
+
}
|
|
5926
|
+
|
|
5927
|
+
// ../../components/ui/MultiCombobox.tsx
|
|
5928
|
+
var React24 = __toESM(require("react"), 1);
|
|
5929
|
+
var import_react15 = require("react");
|
|
5930
|
+
var import_react_dom8 = require("react-dom");
|
|
5931
|
+
var import_lucide_react17 = require("lucide-react");
|
|
5932
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5325
5933
|
var MultiCombobox = ({
|
|
5326
5934
|
id,
|
|
5327
5935
|
options,
|
|
@@ -5340,15 +5948,15 @@ var MultiCombobox = ({
|
|
|
5340
5948
|
required,
|
|
5341
5949
|
displayFormat = (option) => option.label
|
|
5342
5950
|
}) => {
|
|
5343
|
-
const [query, setQuery] =
|
|
5344
|
-
const [open, setOpen] =
|
|
5345
|
-
const [activeIndex, setActiveIndex] =
|
|
5346
|
-
const inputRef =
|
|
5347
|
-
const listRef =
|
|
5348
|
-
const [dropdownPosition, setDropdownPosition] =
|
|
5349
|
-
const triggerRef =
|
|
5951
|
+
const [query, setQuery] = React24.useState("");
|
|
5952
|
+
const [open, setOpen] = React24.useState(false);
|
|
5953
|
+
const [activeIndex, setActiveIndex] = React24.useState(null);
|
|
5954
|
+
const inputRef = React24.useRef(null);
|
|
5955
|
+
const listRef = React24.useRef([]);
|
|
5956
|
+
const [dropdownPosition, setDropdownPosition] = React24.useState(null);
|
|
5957
|
+
const triggerRef = React24.useRef(null);
|
|
5350
5958
|
useShadCNAnimations();
|
|
5351
|
-
const calculatePosition =
|
|
5959
|
+
const calculatePosition = React24.useCallback(() => {
|
|
5352
5960
|
if (!triggerRef.current) return null;
|
|
5353
5961
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
5354
5962
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
@@ -5359,7 +5967,7 @@ var MultiCombobox = ({
|
|
|
5359
5967
|
width: rect.width
|
|
5360
5968
|
};
|
|
5361
5969
|
}, []);
|
|
5362
|
-
|
|
5970
|
+
React24.useEffect(() => {
|
|
5363
5971
|
if (!open) return;
|
|
5364
5972
|
const handler = () => {
|
|
5365
5973
|
const pos = calculatePosition();
|
|
@@ -5372,7 +5980,7 @@ var MultiCombobox = ({
|
|
|
5372
5980
|
window.removeEventListener("scroll", handler, true);
|
|
5373
5981
|
};
|
|
5374
5982
|
}, [open, calculatePosition]);
|
|
5375
|
-
|
|
5983
|
+
React24.useEffect(() => {
|
|
5376
5984
|
if (!open) return;
|
|
5377
5985
|
const handleClickOutside = (event) => {
|
|
5378
5986
|
const target = event.target;
|
|
@@ -5395,12 +6003,12 @@ var MultiCombobox = ({
|
|
|
5395
6003
|
document.removeEventListener("keydown", handleEscape);
|
|
5396
6004
|
};
|
|
5397
6005
|
}, [open]);
|
|
5398
|
-
const normalizedOptions =
|
|
6006
|
+
const normalizedOptions = React24.useMemo(
|
|
5399
6007
|
() => options.map((o) => typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label }),
|
|
5400
6008
|
[options]
|
|
5401
6009
|
);
|
|
5402
6010
|
const enableSearch = normalizedOptions.length > 10;
|
|
5403
|
-
const filtered =
|
|
6011
|
+
const filtered = React24.useMemo(
|
|
5404
6012
|
() => enableSearch ? normalizedOptions.filter((opt) => opt.label.toLowerCase().includes(query.toLowerCase())) : normalizedOptions,
|
|
5405
6013
|
[normalizedOptions, query, enableSearch]
|
|
5406
6014
|
);
|
|
@@ -5429,7 +6037,7 @@ var MultiCombobox = ({
|
|
|
5429
6037
|
const handleClearAll = () => {
|
|
5430
6038
|
onChange([]);
|
|
5431
6039
|
};
|
|
5432
|
-
|
|
6040
|
+
React24.useEffect(() => {
|
|
5433
6041
|
if (open && enableSearch) {
|
|
5434
6042
|
setTimeout(() => {
|
|
5435
6043
|
inputRef.current?.focus();
|
|
@@ -5463,8 +6071,8 @@ var MultiCombobox = ({
|
|
|
5463
6071
|
const resolvedId = id ? String(id) : `multicombobox-${autoId}`;
|
|
5464
6072
|
const labelId = label ? `${resolvedId}-label` : void 0;
|
|
5465
6073
|
const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
|
|
5466
|
-
return /* @__PURE__ */ (0,
|
|
5467
|
-
title && /* @__PURE__ */ (0,
|
|
6074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("w-full space-y-2 group", className), children: [
|
|
6075
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5468
6076
|
"label",
|
|
5469
6077
|
{
|
|
5470
6078
|
className: cn(
|
|
@@ -5474,11 +6082,11 @@ var MultiCombobox = ({
|
|
|
5474
6082
|
),
|
|
5475
6083
|
children: [
|
|
5476
6084
|
title,
|
|
5477
|
-
required && /* @__PURE__ */ (0,
|
|
6085
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive ml-1", children: "*" })
|
|
5478
6086
|
]
|
|
5479
6087
|
}
|
|
5480
6088
|
) }),
|
|
5481
|
-
label && /* @__PURE__ */ (0,
|
|
6089
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5482
6090
|
"label",
|
|
5483
6091
|
{
|
|
5484
6092
|
id: labelId,
|
|
@@ -5490,12 +6098,12 @@ var MultiCombobox = ({
|
|
|
5490
6098
|
),
|
|
5491
6099
|
children: [
|
|
5492
6100
|
label,
|
|
5493
|
-
required && /* @__PURE__ */ (0,
|
|
6101
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive ml-1", children: "*" })
|
|
5494
6102
|
]
|
|
5495
6103
|
}
|
|
5496
6104
|
),
|
|
5497
|
-
/* @__PURE__ */ (0,
|
|
5498
|
-
/* @__PURE__ */ (0,
|
|
6105
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "relative w-full" }),
|
|
6106
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5499
6107
|
"button",
|
|
5500
6108
|
{
|
|
5501
6109
|
ref: triggerRef,
|
|
@@ -5518,11 +6126,11 @@ var MultiCombobox = ({
|
|
|
5518
6126
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
5519
6127
|
),
|
|
5520
6128
|
children: [
|
|
5521
|
-
/* @__PURE__ */ (0,
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center gap-1 flex-wrap min-h-[1.5rem] flex-1", children: value.length > 0 ? showTags ? value.map((itemValue) => {
|
|
5522
6130
|
const option = normalizedOptions.find((o) => o.value === itemValue);
|
|
5523
|
-
return /* @__PURE__ */ (0,
|
|
5524
|
-
/* @__PURE__ */ (0,
|
|
5525
|
-
/* @__PURE__ */ (0,
|
|
6131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "inline-flex items-center gap-1 bg-accent text-accent-foreground rounded px-2 py-1 text-xs", children: [
|
|
6132
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "truncate max-w-[120px]", children: option ? displayFormat(option) : itemValue }),
|
|
6133
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5526
6134
|
"span",
|
|
5527
6135
|
{
|
|
5528
6136
|
role: "button",
|
|
@@ -5545,16 +6153,16 @@ var MultiCombobox = ({
|
|
|
5545
6153
|
}
|
|
5546
6154
|
)
|
|
5547
6155
|
] }, itemValue);
|
|
5548
|
-
}) : /* @__PURE__ */ (0,
|
|
6156
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "truncate text-sm", children: [
|
|
5549
6157
|
value.length,
|
|
5550
6158
|
" selected"
|
|
5551
|
-
] }) : /* @__PURE__ */ (0,
|
|
5552
|
-
/* @__PURE__ */ (0,
|
|
6159
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-muted-foreground", children: placeholder || "Select..." }) }),
|
|
6160
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.ChevronDown, { className: cn("opacity-50 transition-transform", sizeStyles8[size].icon, open && "rotate-180") })
|
|
5553
6161
|
]
|
|
5554
6162
|
}
|
|
5555
6163
|
),
|
|
5556
6164
|
open && dropdownPosition && typeof window !== "undefined" ? (0, import_react_dom8.createPortal)(
|
|
5557
|
-
/* @__PURE__ */ (0,
|
|
6165
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5558
6166
|
"div",
|
|
5559
6167
|
{
|
|
5560
6168
|
"data-dropdown": "multicombobox",
|
|
@@ -5571,7 +6179,7 @@ var MultiCombobox = ({
|
|
|
5571
6179
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
5572
6180
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
5573
6181
|
),
|
|
5574
|
-
children: /* @__PURE__ */ (0,
|
|
6182
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5575
6183
|
"div",
|
|
5576
6184
|
{
|
|
5577
6185
|
className: cn(
|
|
@@ -5579,7 +6187,7 @@ var MultiCombobox = ({
|
|
|
5579
6187
|
"backdrop-blur-sm bg-popover/95 border-border/60"
|
|
5580
6188
|
),
|
|
5581
6189
|
children: [
|
|
5582
|
-
showClear && value.length > 0 && /* @__PURE__ */ (0,
|
|
6190
|
+
showClear && value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "px-3 py-2 border-b border-border/60 flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5583
6191
|
"button",
|
|
5584
6192
|
{
|
|
5585
6193
|
type: "button",
|
|
@@ -5592,9 +6200,9 @@ var MultiCombobox = ({
|
|
|
5592
6200
|
children: "Clear all"
|
|
5593
6201
|
}
|
|
5594
6202
|
) }),
|
|
5595
|
-
enableSearch && /* @__PURE__ */ (0,
|
|
5596
|
-
/* @__PURE__ */ (0,
|
|
5597
|
-
/* @__PURE__ */ (0,
|
|
6203
|
+
enableSearch && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "relative border-b border-border/60", children: [
|
|
6204
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.Search, { className: cn("absolute left-2 top-2.5 text-muted-foreground", sizeStyles8[size].icon) }),
|
|
6205
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5598
6206
|
"input",
|
|
5599
6207
|
{
|
|
5600
6208
|
ref: inputRef,
|
|
@@ -5609,10 +6217,10 @@ var MultiCombobox = ({
|
|
|
5609
6217
|
}
|
|
5610
6218
|
)
|
|
5611
6219
|
] }),
|
|
5612
|
-
/* @__PURE__ */ (0,
|
|
6220
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { className: cn("max-h-60 overflow-y-auto p-1", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: filtered.length ? filtered.map((item, index) => {
|
|
5613
6221
|
const isSelected = value.includes(item.value);
|
|
5614
6222
|
const isDisabled = disabledOptions.includes(item.value);
|
|
5615
|
-
return /* @__PURE__ */ (0,
|
|
6223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5616
6224
|
"li",
|
|
5617
6225
|
{
|
|
5618
6226
|
ref: (node) => {
|
|
@@ -5636,12 +6244,12 @@ var MultiCombobox = ({
|
|
|
5636
6244
|
),
|
|
5637
6245
|
children: [
|
|
5638
6246
|
item.label,
|
|
5639
|
-
isSelected && /* @__PURE__ */ (0,
|
|
6247
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.Check, { className: sizeStyles8[size].icon })
|
|
5640
6248
|
]
|
|
5641
6249
|
},
|
|
5642
6250
|
item.value
|
|
5643
6251
|
);
|
|
5644
|
-
}) : /* @__PURE__ */ (0,
|
|
6252
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("li", { className: cn("px-3 py-2 text-muted-foreground", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: "No result." }) })
|
|
5645
6253
|
]
|
|
5646
6254
|
}
|
|
5647
6255
|
)
|
|
@@ -5653,17 +6261,17 @@ var MultiCombobox = ({
|
|
|
5653
6261
|
};
|
|
5654
6262
|
|
|
5655
6263
|
// ../../components/ui/RadioGroup.tsx
|
|
5656
|
-
var
|
|
5657
|
-
var
|
|
5658
|
-
var RadioGroupContext =
|
|
6264
|
+
var React25 = __toESM(require("react"), 1);
|
|
6265
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
6266
|
+
var RadioGroupContext = React25.createContext(void 0);
|
|
5659
6267
|
var useRadioGroup = () => {
|
|
5660
|
-
const context =
|
|
6268
|
+
const context = React25.useContext(RadioGroupContext);
|
|
5661
6269
|
if (!context) {
|
|
5662
6270
|
throw new Error("RadioGroupItem must be used within a RadioGroup");
|
|
5663
6271
|
}
|
|
5664
6272
|
return context;
|
|
5665
6273
|
};
|
|
5666
|
-
var RadioGroup =
|
|
6274
|
+
var RadioGroup = React25.forwardRef(
|
|
5667
6275
|
({
|
|
5668
6276
|
value,
|
|
5669
6277
|
defaultValue,
|
|
@@ -5679,7 +6287,7 @@ var RadioGroup = React23.forwardRef(
|
|
|
5679
6287
|
error = false,
|
|
5680
6288
|
errorMessage
|
|
5681
6289
|
}, ref) => {
|
|
5682
|
-
const [internalValue, setInternalValue] =
|
|
6290
|
+
const [internalValue, setInternalValue] = React25.useState(defaultValue || "");
|
|
5683
6291
|
const isControlled = value !== void 0;
|
|
5684
6292
|
const currentValue = isControlled ? value : internalValue;
|
|
5685
6293
|
const handleValueChange = (newValue) => {
|
|
@@ -5690,9 +6298,9 @@ var RadioGroup = React23.forwardRef(
|
|
|
5690
6298
|
onValueChange?.(newValue);
|
|
5691
6299
|
}
|
|
5692
6300
|
};
|
|
5693
|
-
const uniqueId =
|
|
6301
|
+
const uniqueId = React25.useId();
|
|
5694
6302
|
const radioName = name || `radio-group-${uniqueId}`;
|
|
5695
|
-
return /* @__PURE__ */ (0,
|
|
6303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5696
6304
|
RadioGroupContext.Provider,
|
|
5697
6305
|
{
|
|
5698
6306
|
value: {
|
|
@@ -5703,8 +6311,8 @@ var RadioGroup = React23.forwardRef(
|
|
|
5703
6311
|
size,
|
|
5704
6312
|
variant
|
|
5705
6313
|
},
|
|
5706
|
-
children: /* @__PURE__ */ (0,
|
|
5707
|
-
/* @__PURE__ */ (0,
|
|
6314
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "space-y-2", children: [
|
|
6315
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5708
6316
|
"div",
|
|
5709
6317
|
{
|
|
5710
6318
|
ref,
|
|
@@ -5721,7 +6329,7 @@ var RadioGroup = React23.forwardRef(
|
|
|
5721
6329
|
children
|
|
5722
6330
|
}
|
|
5723
6331
|
),
|
|
5724
|
-
error && errorMessage && /* @__PURE__ */ (0,
|
|
6332
|
+
error && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-sm text-destructive mt-1", children: errorMessage })
|
|
5725
6333
|
] })
|
|
5726
6334
|
}
|
|
5727
6335
|
);
|
|
@@ -5748,7 +6356,7 @@ var sizeStyles7 = {
|
|
|
5748
6356
|
padding: "p-4"
|
|
5749
6357
|
}
|
|
5750
6358
|
};
|
|
5751
|
-
var RadioGroupItem =
|
|
6359
|
+
var RadioGroupItem = React25.forwardRef(
|
|
5752
6360
|
({ value, id, disabled, className, children, label, description, icon }, ref) => {
|
|
5753
6361
|
const {
|
|
5754
6362
|
value: selectedValue,
|
|
@@ -5763,7 +6371,7 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5763
6371
|
const Icon = icon;
|
|
5764
6372
|
const radioId = id || `radio-${value}`;
|
|
5765
6373
|
if (variant === "card") {
|
|
5766
|
-
return /* @__PURE__ */ (0,
|
|
6374
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5767
6375
|
"div",
|
|
5768
6376
|
{
|
|
5769
6377
|
className: cn(
|
|
@@ -5775,8 +6383,8 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5775
6383
|
className
|
|
5776
6384
|
),
|
|
5777
6385
|
children: [
|
|
5778
|
-
/* @__PURE__ */ (0,
|
|
5779
|
-
/* @__PURE__ */ (0,
|
|
6386
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
6387
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5780
6388
|
"button",
|
|
5781
6389
|
{
|
|
5782
6390
|
ref,
|
|
@@ -5795,22 +6403,22 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5795
6403
|
sizeStyles7[size].radio
|
|
5796
6404
|
),
|
|
5797
6405
|
onClick: () => onValueChange?.(value),
|
|
5798
|
-
children: /* @__PURE__ */ (0,
|
|
6406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5799
6407
|
"span",
|
|
5800
6408
|
{
|
|
5801
6409
|
className: cn(
|
|
5802
6410
|
"flex items-center justify-center w-full h-full rounded-full transition-all duration-200",
|
|
5803
6411
|
isSelected && "bg-primary"
|
|
5804
6412
|
),
|
|
5805
|
-
children: isSelected && /* @__PURE__ */ (0,
|
|
6413
|
+
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn("bg-primary-foreground rounded-full", sizeStyles7[size].dot) })
|
|
5806
6414
|
}
|
|
5807
6415
|
)
|
|
5808
6416
|
}
|
|
5809
6417
|
),
|
|
5810
|
-
/* @__PURE__ */ (0,
|
|
5811
|
-
/* @__PURE__ */ (0,
|
|
5812
|
-
Icon && /* @__PURE__ */ (0,
|
|
5813
|
-
/* @__PURE__ */ (0,
|
|
6418
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
6419
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6420
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { className: "h-4 w-4 text-foreground" }),
|
|
6421
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5814
6422
|
"label",
|
|
5815
6423
|
{
|
|
5816
6424
|
htmlFor: radioId,
|
|
@@ -5822,10 +6430,10 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5822
6430
|
}
|
|
5823
6431
|
)
|
|
5824
6432
|
] }),
|
|
5825
|
-
description && /* @__PURE__ */ (0,
|
|
6433
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-muted-foreground mt-1 text-xs", children: description })
|
|
5826
6434
|
] })
|
|
5827
6435
|
] }),
|
|
5828
|
-
/* @__PURE__ */ (0,
|
|
6436
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5829
6437
|
"input",
|
|
5830
6438
|
{
|
|
5831
6439
|
type: "radio",
|
|
@@ -5843,7 +6451,7 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5843
6451
|
);
|
|
5844
6452
|
}
|
|
5845
6453
|
if (variant === "button") {
|
|
5846
|
-
return /* @__PURE__ */ (0,
|
|
6454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5847
6455
|
"button",
|
|
5848
6456
|
{
|
|
5849
6457
|
ref,
|
|
@@ -5865,9 +6473,9 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5865
6473
|
),
|
|
5866
6474
|
onClick: () => onValueChange?.(value),
|
|
5867
6475
|
children: [
|
|
5868
|
-
Icon && /* @__PURE__ */ (0,
|
|
6476
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { className: "h-4 w-4" }),
|
|
5869
6477
|
label || children,
|
|
5870
|
-
/* @__PURE__ */ (0,
|
|
6478
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5871
6479
|
"input",
|
|
5872
6480
|
{
|
|
5873
6481
|
type: "radio",
|
|
@@ -5884,8 +6492,8 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5884
6492
|
}
|
|
5885
6493
|
);
|
|
5886
6494
|
}
|
|
5887
|
-
return /* @__PURE__ */ (0,
|
|
5888
|
-
/* @__PURE__ */ (0,
|
|
6495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cn("flex items-center gap-2", className), children: [
|
|
6496
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5889
6497
|
"button",
|
|
5890
6498
|
{
|
|
5891
6499
|
ref,
|
|
@@ -5904,19 +6512,19 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5904
6512
|
sizeStyles7[size].radio
|
|
5905
6513
|
),
|
|
5906
6514
|
onClick: () => onValueChange?.(value),
|
|
5907
|
-
children: /* @__PURE__ */ (0,
|
|
6515
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5908
6516
|
"span",
|
|
5909
6517
|
{
|
|
5910
6518
|
className: cn(
|
|
5911
6519
|
"flex items-center justify-center w-full h-full rounded-full transition-all duration-200",
|
|
5912
6520
|
isSelected && "bg-primary"
|
|
5913
6521
|
),
|
|
5914
|
-
children: isSelected && /* @__PURE__ */ (0,
|
|
6522
|
+
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn("bg-primary-foreground rounded-full", sizeStyles7[size].dot) })
|
|
5915
6523
|
}
|
|
5916
6524
|
)
|
|
5917
6525
|
}
|
|
5918
6526
|
),
|
|
5919
|
-
(label || children) && /* @__PURE__ */ (0,
|
|
6527
|
+
(label || children) && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5920
6528
|
"label",
|
|
5921
6529
|
{
|
|
5922
6530
|
htmlFor: radioId,
|
|
@@ -5927,15 +6535,15 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5927
6535
|
isDisabled && "cursor-not-allowed opacity-50"
|
|
5928
6536
|
),
|
|
5929
6537
|
children: [
|
|
5930
|
-
/* @__PURE__ */ (0,
|
|
5931
|
-
Icon && /* @__PURE__ */ (0,
|
|
5932
|
-
/* @__PURE__ */ (0,
|
|
6538
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6539
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { className: "h-4 w-4" }),
|
|
6540
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: label || children })
|
|
5933
6541
|
] }),
|
|
5934
|
-
description && /* @__PURE__ */ (0,
|
|
6542
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-muted-foreground mt-0.5 text-xs", children: description })
|
|
5935
6543
|
]
|
|
5936
6544
|
}
|
|
5937
6545
|
),
|
|
5938
|
-
/* @__PURE__ */ (0,
|
|
6546
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5939
6547
|
"input",
|
|
5940
6548
|
{
|
|
5941
6549
|
type: "radio",
|
|
@@ -5954,8 +6562,8 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5954
6562
|
RadioGroupItem.displayName = "RadioGroupItem";
|
|
5955
6563
|
|
|
5956
6564
|
// ../../components/ui/Slider.tsx
|
|
5957
|
-
var
|
|
5958
|
-
var
|
|
6565
|
+
var React26 = __toESM(require("react"), 1);
|
|
6566
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
5959
6567
|
var SIZE_STYLES = {
|
|
5960
6568
|
sm: {
|
|
5961
6569
|
track: "h-1",
|
|
@@ -5973,7 +6581,7 @@ var SIZE_STYLES = {
|
|
|
5973
6581
|
container: "py-3"
|
|
5974
6582
|
}
|
|
5975
6583
|
};
|
|
5976
|
-
var Slider =
|
|
6584
|
+
var Slider = React26.forwardRef(
|
|
5977
6585
|
({
|
|
5978
6586
|
className,
|
|
5979
6587
|
value,
|
|
@@ -5999,7 +6607,7 @@ var Slider = React24.forwardRef(
|
|
|
5999
6607
|
noFocus = false,
|
|
6000
6608
|
...props
|
|
6001
6609
|
}, ref) => {
|
|
6002
|
-
const [internalValue, setInternalValue] =
|
|
6610
|
+
const [internalValue, setInternalValue] = React26.useState(defaultValue);
|
|
6003
6611
|
const isControlled = value !== void 0;
|
|
6004
6612
|
const currentValue = isControlled ? value : internalValue;
|
|
6005
6613
|
const handleChange = (e) => {
|
|
@@ -6015,20 +6623,20 @@ var Slider = React24.forwardRef(
|
|
|
6015
6623
|
const displayValue = formatValue ? formatValue(currentValue) : currentValue.toString();
|
|
6016
6624
|
if (orientation === "vertical") {
|
|
6017
6625
|
}
|
|
6018
|
-
return /* @__PURE__ */ (0,
|
|
6019
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
6020
|
-
label && /* @__PURE__ */ (0,
|
|
6021
|
-
showValue && /* @__PURE__ */ (0,
|
|
6626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cn("w-full space-y-2", containerClassName), children: [
|
|
6627
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6628
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
|
|
6629
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: cn("text-xs font-mono text-muted-foreground min-w-[2rem] text-right", valueClassName), children: displayValue })
|
|
6022
6630
|
] }),
|
|
6023
|
-
/* @__PURE__ */ (0,
|
|
6024
|
-
/* @__PURE__ */ (0,
|
|
6631
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cn("relative flex items-center", sizeStyles8.container), children: [
|
|
6632
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden", sizeStyles8.track, trackClassName), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
6025
6633
|
"div",
|
|
6026
6634
|
{
|
|
6027
6635
|
className: "absolute left-0 top-0 h-full bg-primary rounded-full transition-all duration-150 ease-out",
|
|
6028
6636
|
style: { width: `${percentage}%` }
|
|
6029
6637
|
}
|
|
6030
6638
|
) }),
|
|
6031
|
-
/* @__PURE__ */ (0,
|
|
6639
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
6032
6640
|
"input",
|
|
6033
6641
|
{
|
|
6034
6642
|
ref,
|
|
@@ -6092,9 +6700,9 @@ var Slider = React24.forwardRef(
|
|
|
6092
6700
|
Slider.displayName = "Slider";
|
|
6093
6701
|
|
|
6094
6702
|
// ../../components/ui/OverlayControls.tsx
|
|
6095
|
-
var
|
|
6703
|
+
var import_lucide_react18 = require("lucide-react");
|
|
6096
6704
|
var import_react16 = __toESM(require("react"), 1);
|
|
6097
|
-
var
|
|
6705
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
6098
6706
|
function OverlayControls({
|
|
6099
6707
|
mode,
|
|
6100
6708
|
value,
|
|
@@ -6297,7 +6905,7 @@ function OverlayControls({
|
|
|
6297
6905
|
playing,
|
|
6298
6906
|
muted
|
|
6299
6907
|
]);
|
|
6300
|
-
const
|
|
6908
|
+
const formatTime3 = (sec) => {
|
|
6301
6909
|
if (!isFinite(sec) || sec < 0) return "0:00";
|
|
6302
6910
|
const h = Math.floor(sec / 3600);
|
|
6303
6911
|
const m = Math.floor(sec % 3600 / 60);
|
|
@@ -6317,41 +6925,41 @@ function OverlayControls({
|
|
|
6317
6925
|
const handleSliderMouseLeave = () => {
|
|
6318
6926
|
setPreviewData(null);
|
|
6319
6927
|
};
|
|
6320
|
-
return /* @__PURE__ */ (0,
|
|
6321
|
-
keyboardFeedback && /* @__PURE__ */ (0,
|
|
6928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
6929
|
+
keyboardFeedback && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6322
6930
|
"div",
|
|
6323
6931
|
{
|
|
6324
6932
|
className: cn(
|
|
6325
6933
|
"absolute inset-0 flex items-center pointer-events-none z-50",
|
|
6326
6934
|
keyboardFeedback.type === "seek" && (keyboardFeedback.value ?? 0) > 0 ? "justify-end pr-32" : keyboardFeedback.type === "seek" && (keyboardFeedback.value ?? 0) < 0 ? "justify-start pl-32" : "justify-center"
|
|
6327
6935
|
),
|
|
6328
|
-
children: /* @__PURE__ */ (0,
|
|
6329
|
-
keyboardFeedback.type === "play" && /* @__PURE__ */ (0,
|
|
6330
|
-
keyboardFeedback.type === "pause" && /* @__PURE__ */ (0,
|
|
6331
|
-
keyboardFeedback.type === "seek" && /* @__PURE__ */ (0,
|
|
6332
|
-
(keyboardFeedback.value ?? 0) > 0 ? /* @__PURE__ */ (0,
|
|
6333
|
-
/* @__PURE__ */ (0,
|
|
6936
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "bg-black/50 backdrop-blur-sm rounded-xl px-6 py-4 shadow-xl border border-white/10 animate-in fade-in zoom-in duration-200", children: [
|
|
6937
|
+
keyboardFeedback.type === "play" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Play, { className: "w-16 h-16 text-white", fill: "white" }),
|
|
6938
|
+
keyboardFeedback.type === "pause" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Pause, { className: "w-16 h-16 text-white", fill: "white" }),
|
|
6939
|
+
keyboardFeedback.type === "seek" && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
6940
|
+
(keyboardFeedback.value ?? 0) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.RotateCw, { className: "w-12 h-12 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.RotateCcw, { className: "w-12 h-12 text-white" }),
|
|
6941
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-3xl font-bold text-white", children: [
|
|
6334
6942
|
keyboardFeedback.value && keyboardFeedback.value > 0 ? "+" : "",
|
|
6335
6943
|
keyboardFeedback.value,
|
|
6336
6944
|
"s"
|
|
6337
6945
|
] })
|
|
6338
6946
|
] }),
|
|
6339
|
-
keyboardFeedback.type === "volume" && /* @__PURE__ */ (0,
|
|
6340
|
-
/* @__PURE__ */ (0,
|
|
6341
|
-
/* @__PURE__ */ (0,
|
|
6342
|
-
/* @__PURE__ */ (0,
|
|
6947
|
+
keyboardFeedback.type === "volume" && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
6948
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Volume2, { className: "w-12 h-12 text-white" }),
|
|
6949
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
6950
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-2xl font-bold text-white", children: [
|
|
6343
6951
|
keyboardFeedback.value,
|
|
6344
6952
|
"%"
|
|
6345
6953
|
] }),
|
|
6346
|
-
/* @__PURE__ */ (0,
|
|
6954
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "w-32 h-1.5 bg-white/30 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "h-full bg-white rounded-full transition-all", style: { width: `${keyboardFeedback.value}%` } }) })
|
|
6347
6955
|
] })
|
|
6348
6956
|
] }),
|
|
6349
|
-
keyboardFeedback.type === "mute" && /* @__PURE__ */ (0,
|
|
6350
|
-
keyboardFeedback.type === "unmute" && /* @__PURE__ */ (0,
|
|
6957
|
+
keyboardFeedback.type === "mute" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.VolumeX, { className: "w-16 h-16 text-white" }),
|
|
6958
|
+
keyboardFeedback.type === "unmute" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Volume2, { className: "w-16 h-16 text-white" })
|
|
6351
6959
|
] })
|
|
6352
6960
|
}
|
|
6353
6961
|
),
|
|
6354
|
-
/* @__PURE__ */ (0,
|
|
6962
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6355
6963
|
"div",
|
|
6356
6964
|
{
|
|
6357
6965
|
className: cn(
|
|
@@ -6360,9 +6968,9 @@ function OverlayControls({
|
|
|
6360
6968
|
autoHide && !controlsVisible && "opacity-0 pointer-events-none",
|
|
6361
6969
|
className
|
|
6362
6970
|
),
|
|
6363
|
-
children: /* @__PURE__ */ (0,
|
|
6364
|
-
/* @__PURE__ */ (0,
|
|
6365
|
-
/* @__PURE__ */ (0,
|
|
6971
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "px-4", children: [
|
|
6972
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { ref: sliderRef, onMouseMove: handleSliderMouseMove, onMouseLeave: handleSliderMouseLeave, className: "relative", children: [
|
|
6973
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6366
6974
|
Slider,
|
|
6367
6975
|
{
|
|
6368
6976
|
min: 0,
|
|
@@ -6387,14 +6995,14 @@ function OverlayControls({
|
|
|
6387
6995
|
noFocus: true
|
|
6388
6996
|
}
|
|
6389
6997
|
),
|
|
6390
|
-
previewData && /* @__PURE__ */ (0,
|
|
6391
|
-
/* @__PURE__ */ (0,
|
|
6392
|
-
/* @__PURE__ */ (0,
|
|
6393
|
-
] }) : /* @__PURE__ */ (0,
|
|
6998
|
+
previewData && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "absolute bottom-full mb-2 transform -translate-x-1/2 pointer-events-none z-30", style: { left: `${previewData.x}px` }, children: previewData.url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "bg-background/95 backdrop-blur rounded-md border border-border shadow-lg overflow-hidden", children: [
|
|
6999
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("img", { src: previewData.url, alt: "Preview", className: "w-40 h-24 object-cover" }),
|
|
7000
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-2 py-1 text-xs font-mono text-center bg-background/80", children: formatTime3(previewData.time) })
|
|
7001
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 py-1.5 rounded-md bg-background/90 backdrop-blur border border-border shadow-lg", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs font-mono text-center", children: formatTime3(previewData.time) }) }) })
|
|
6394
7002
|
] }),
|
|
6395
|
-
showControlsBar && /* @__PURE__ */ (0,
|
|
6396
|
-
/* @__PURE__ */ (0,
|
|
6397
|
-
/* @__PURE__ */ (0,
|
|
7003
|
+
showControlsBar && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "mt-2 flex items-center justify-between gap-2", children: [
|
|
7004
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7005
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6398
7006
|
Button_default,
|
|
6399
7007
|
{
|
|
6400
7008
|
variant: "ghost",
|
|
@@ -6402,10 +7010,10 @@ function OverlayControls({
|
|
|
6402
7010
|
onClick: onTogglePlay,
|
|
6403
7011
|
title: playing ? "T\u1EA1m d\u1EEBng" : "Ph\xE1t",
|
|
6404
7012
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6405
|
-
children: playing ? /* @__PURE__ */ (0,
|
|
7013
|
+
children: playing ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Pause, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Play, { className: "w-4 h-4" })
|
|
6406
7014
|
}
|
|
6407
7015
|
),
|
|
6408
|
-
onSkip && /* @__PURE__ */ (0,
|
|
7016
|
+
onSkip && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6409
7017
|
Button_default,
|
|
6410
7018
|
{
|
|
6411
7019
|
variant: "ghost",
|
|
@@ -6413,10 +7021,10 @@ function OverlayControls({
|
|
|
6413
7021
|
onClick: () => onSkip(-skipSeconds),
|
|
6414
7022
|
title: `L\xF9i ${skipSeconds}s`,
|
|
6415
7023
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6416
|
-
children: /* @__PURE__ */ (0,
|
|
7024
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.RotateCcw, { className: "w-4 h-4" })
|
|
6417
7025
|
}
|
|
6418
7026
|
),
|
|
6419
|
-
onSkip && /* @__PURE__ */ (0,
|
|
7027
|
+
onSkip && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6420
7028
|
Button_default,
|
|
6421
7029
|
{
|
|
6422
7030
|
variant: "ghost",
|
|
@@ -6424,16 +7032,16 @@ function OverlayControls({
|
|
|
6424
7032
|
onClick: () => onSkip(skipSeconds),
|
|
6425
7033
|
title: `Tua ${skipSeconds}s`,
|
|
6426
7034
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6427
|
-
children: /* @__PURE__ */ (0,
|
|
7035
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.RotateCw, { className: "w-4 h-4" })
|
|
6428
7036
|
}
|
|
6429
7037
|
),
|
|
6430
|
-
(showTime ?? true) && /* @__PURE__ */ (0,
|
|
6431
|
-
|
|
7038
|
+
(showTime ?? true) && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "px-3 py-1 rounded-full text-xs font-mono bg-background/60 text-foreground shadow-sm border border-border whitespace-nowrap", children: [
|
|
7039
|
+
formatTime3(dragValue),
|
|
6432
7040
|
" / ",
|
|
6433
|
-
|
|
7041
|
+
formatTime3(max)
|
|
6434
7042
|
] }),
|
|
6435
|
-
/* @__PURE__ */ (0,
|
|
6436
|
-
/* @__PURE__ */ (0,
|
|
7043
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7044
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6437
7045
|
Button_default,
|
|
6438
7046
|
{
|
|
6439
7047
|
variant: "ghost",
|
|
@@ -6441,10 +7049,10 @@ function OverlayControls({
|
|
|
6441
7049
|
onClick: onToggleMute,
|
|
6442
7050
|
title: muted ? "B\u1EADt ti\u1EBFng" : "T\u1EAFt ti\u1EBFng",
|
|
6443
7051
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6444
|
-
children: muted || (volume ?? 1) === 0 ? /* @__PURE__ */ (0,
|
|
7052
|
+
children: muted || (volume ?? 1) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.VolumeX, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Volume2, { className: "w-4 h-4" })
|
|
6445
7053
|
}
|
|
6446
7054
|
),
|
|
6447
|
-
/* @__PURE__ */ (0,
|
|
7055
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "w-24", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6448
7056
|
Slider,
|
|
6449
7057
|
{
|
|
6450
7058
|
min: 0,
|
|
@@ -6459,8 +7067,8 @@ function OverlayControls({
|
|
|
6459
7067
|
) })
|
|
6460
7068
|
] })
|
|
6461
7069
|
] }),
|
|
6462
|
-
/* @__PURE__ */ (0,
|
|
6463
|
-
onGoLive && /* @__PURE__ */ (0,
|
|
7070
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2 relative", children: [
|
|
7071
|
+
onGoLive && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
6464
7072
|
Button_default,
|
|
6465
7073
|
{
|
|
6466
7074
|
variant: "ghost",
|
|
@@ -6469,13 +7077,13 @@ function OverlayControls({
|
|
|
6469
7077
|
title: "Tr\u1EF1c ti\u1EBFp (v\u1EC1 Live)",
|
|
6470
7078
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6471
7079
|
children: [
|
|
6472
|
-
/* @__PURE__ */ (0,
|
|
7080
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Dot, { className: "w-10 h-10 text-destructive" }),
|
|
6473
7081
|
"Tr\u1EF1c ti\u1EBFp"
|
|
6474
7082
|
]
|
|
6475
7083
|
}
|
|
6476
7084
|
),
|
|
6477
|
-
onChangeRate && /* @__PURE__ */ (0,
|
|
6478
|
-
/* @__PURE__ */ (0,
|
|
7085
|
+
onChangeRate && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative", ref: rateWrapRef, children: [
|
|
7086
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
6479
7087
|
Button_default,
|
|
6480
7088
|
{
|
|
6481
7089
|
variant: "ghost",
|
|
@@ -6489,7 +7097,7 @@ function OverlayControls({
|
|
|
6489
7097
|
]
|
|
6490
7098
|
}
|
|
6491
7099
|
),
|
|
6492
|
-
rateOpen && /* @__PURE__ */ (0,
|
|
7100
|
+
rateOpen && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "absolute bottom-9 right-0 bg-background/90 backdrop-blur rounded-md border border-border shadow-lg p-1 z-30", children: [0.5, 0.75, 1, 1.25, 1.5].map((r) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
6493
7101
|
"button",
|
|
6494
7102
|
{
|
|
6495
7103
|
onClick: () => {
|
|
@@ -6505,7 +7113,7 @@ function OverlayControls({
|
|
|
6505
7113
|
r
|
|
6506
7114
|
)) })
|
|
6507
7115
|
] }),
|
|
6508
|
-
onToggleFullscreen && /* @__PURE__ */ (0,
|
|
7116
|
+
onToggleFullscreen && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
6509
7117
|
Button_default,
|
|
6510
7118
|
{
|
|
6511
7119
|
variant: "ghost",
|
|
@@ -6513,7 +7121,7 @@ function OverlayControls({
|
|
|
6513
7121
|
onClick: onToggleFullscreen,
|
|
6514
7122
|
title: "To\xE0n m\xE0n h\xECnh",
|
|
6515
7123
|
className: "px-3 bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6516
|
-
children: /* @__PURE__ */ (0,
|
|
7124
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Maximize2, { className: "w-4 h-4" })
|
|
6517
7125
|
}
|
|
6518
7126
|
)
|
|
6519
7127
|
] })
|
|
@@ -6526,8 +7134,8 @@ function OverlayControls({
|
|
|
6526
7134
|
|
|
6527
7135
|
// ../../components/ui/CategoryTreeSelect.tsx
|
|
6528
7136
|
var import_react17 = require("react");
|
|
6529
|
-
var
|
|
6530
|
-
var
|
|
7137
|
+
var import_lucide_react19 = require("lucide-react");
|
|
7138
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
6531
7139
|
function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1ECDn danh m\u1EE5c", disabled }) {
|
|
6532
7140
|
const [isOpen, setIsOpen] = (0, import_react17.useState)(false);
|
|
6533
7141
|
const [expandedNodes, setExpandedNodes] = (0, import_react17.useState)(/* @__PURE__ */ new Set());
|
|
@@ -6569,8 +7177,8 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6569
7177
|
const hasChildren = children.length > 0;
|
|
6570
7178
|
const isExpanded = expandedNodes.has(category.id);
|
|
6571
7179
|
const isSelected = value.includes(category.id);
|
|
6572
|
-
return /* @__PURE__ */ (0,
|
|
6573
|
-
/* @__PURE__ */ (0,
|
|
7180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
|
|
7181
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
6574
7182
|
"div",
|
|
6575
7183
|
{
|
|
6576
7184
|
className: cn(
|
|
@@ -6581,14 +7189,14 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6581
7189
|
),
|
|
6582
7190
|
style: { paddingLeft: `${level * 1.5 + 0.75}rem` },
|
|
6583
7191
|
children: [
|
|
6584
|
-
isSelected && /* @__PURE__ */ (0,
|
|
7192
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6585
7193
|
"span",
|
|
6586
7194
|
{
|
|
6587
7195
|
"aria-hidden": true,
|
|
6588
7196
|
className: "absolute left-0 top-0 bottom-0 w-1 bg-primary"
|
|
6589
7197
|
}
|
|
6590
7198
|
),
|
|
6591
|
-
hasChildren ? /* @__PURE__ */ (0,
|
|
7199
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6592
7200
|
"button",
|
|
6593
7201
|
{
|
|
6594
7202
|
type: "button",
|
|
@@ -6597,39 +7205,39 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6597
7205
|
toggleExpand(category.id);
|
|
6598
7206
|
},
|
|
6599
7207
|
className: "p-0.5 hover:bg-accent rounded",
|
|
6600
|
-
children: isExpanded ? /* @__PURE__ */ (0,
|
|
7208
|
+
children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react19.ChevronDown, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react19.ChevronRight, { className: "w-4 h-4" })
|
|
6601
7209
|
}
|
|
6602
|
-
) : /* @__PURE__ */ (0,
|
|
6603
|
-
/* @__PURE__ */ (0,
|
|
7210
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "w-5" }),
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
6604
7212
|
"div",
|
|
6605
7213
|
{
|
|
6606
7214
|
onClick: () => handleSelect(category.id, category),
|
|
6607
7215
|
className: "flex items-center gap-2 flex-1",
|
|
6608
7216
|
children: [
|
|
6609
|
-
/* @__PURE__ */ (0,
|
|
7217
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6610
7218
|
"div",
|
|
6611
7219
|
{
|
|
6612
7220
|
className: cn(
|
|
6613
7221
|
"w-4 h-4 border-2 rounded flex items-center justify-center transition-colors",
|
|
6614
7222
|
isSelected ? "bg-primary border-primary" : "border-muted-foreground/30"
|
|
6615
7223
|
),
|
|
6616
|
-
children: isSelected && /* @__PURE__ */ (0,
|
|
7224
|
+
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react19.Check, { className: "w-3 h-3 text-primary-foreground" })
|
|
6617
7225
|
}
|
|
6618
7226
|
),
|
|
6619
|
-
/* @__PURE__ */ (0,
|
|
7227
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn("text-sm", isSelected && "font-medium text-primary"), children: category.name })
|
|
6620
7228
|
]
|
|
6621
7229
|
}
|
|
6622
7230
|
)
|
|
6623
7231
|
]
|
|
6624
7232
|
}
|
|
6625
7233
|
),
|
|
6626
|
-
hasChildren && isExpanded && /* @__PURE__ */ (0,
|
|
7234
|
+
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { children: children.map((child) => renderCategory(child, level + 1)) })
|
|
6627
7235
|
] }, category.id);
|
|
6628
7236
|
};
|
|
6629
7237
|
const selectedCount = value.length;
|
|
6630
7238
|
const displayText = selectedCount > 0 ? `\u0110\xE3 ch\u1ECDn ${selectedCount} danh m\u1EE5c` : placeholder;
|
|
6631
|
-
return /* @__PURE__ */ (0,
|
|
6632
|
-
/* @__PURE__ */ (0,
|
|
7239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "relative", children: [
|
|
7240
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
6633
7241
|
"button",
|
|
6634
7242
|
{
|
|
6635
7243
|
type: "button",
|
|
@@ -6645,14 +7253,14 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6645
7253
|
isOpen && "border-primary"
|
|
6646
7254
|
),
|
|
6647
7255
|
children: [
|
|
6648
|
-
/* @__PURE__ */ (0,
|
|
6649
|
-
/* @__PURE__ */ (0,
|
|
7256
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn("text-sm", selectedCount === 0 && "text-muted-foreground"), children: displayText }),
|
|
7257
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react19.ChevronDown, { className: cn("w-4 h-4 transition-transform", isOpen && "transform rotate-180") })
|
|
6650
7258
|
]
|
|
6651
7259
|
}
|
|
6652
7260
|
),
|
|
6653
|
-
isOpen && !disabled && /* @__PURE__ */ (0,
|
|
6654
|
-
/* @__PURE__ */ (0,
|
|
6655
|
-
/* @__PURE__ */ (0,
|
|
7261
|
+
isOpen && !disabled && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
7262
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "fixed inset-0 z-10", onClick: () => setIsOpen(false) }),
|
|
7263
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6656
7264
|
"div",
|
|
6657
7265
|
{
|
|
6658
7266
|
className: cn(
|
|
@@ -6660,7 +7268,7 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6660
7268
|
"rounded-md border bg-popover text-popover-foreground shadow-md",
|
|
6661
7269
|
"backdrop-blur-sm bg-popover/95 border-border/60"
|
|
6662
7270
|
),
|
|
6663
|
-
children: /* @__PURE__ */ (0,
|
|
7271
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "p-1", children: parentCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "Kh\xF4ng c\xF3 danh m\u1EE5c n\xE0o" }) : parentCategories.map((cat) => renderCategory(cat)) })
|
|
6664
7272
|
}
|
|
6665
7273
|
)
|
|
6666
7274
|
] })
|
|
@@ -6669,9 +7277,9 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6669
7277
|
|
|
6670
7278
|
// ../../components/ui/ImageUpload.tsx
|
|
6671
7279
|
var import_react18 = require("react");
|
|
6672
|
-
var
|
|
7280
|
+
var import_lucide_react20 = require("lucide-react");
|
|
6673
7281
|
var import_next_intl6 = require("next-intl");
|
|
6674
|
-
var
|
|
7282
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
6675
7283
|
function ImageUpload({
|
|
6676
7284
|
onUpload,
|
|
6677
7285
|
onRemove,
|
|
@@ -6793,8 +7401,8 @@ function ImageUpload({
|
|
|
6793
7401
|
const handleBrowseClick = () => {
|
|
6794
7402
|
fileInputRef.current?.click();
|
|
6795
7403
|
};
|
|
6796
|
-
return /* @__PURE__ */ (0,
|
|
6797
|
-
/* @__PURE__ */ (0,
|
|
7404
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("space-y-4", className), children: [
|
|
7405
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
6798
7406
|
"div",
|
|
6799
7407
|
{
|
|
6800
7408
|
className: cn(
|
|
@@ -6807,15 +7415,15 @@ function ImageUpload({
|
|
|
6807
7415
|
onDragLeave: handleDragLeave,
|
|
6808
7416
|
onDrop: handleDrop,
|
|
6809
7417
|
children: [
|
|
6810
|
-
uploading && /* @__PURE__ */ (0,
|
|
6811
|
-
/* @__PURE__ */ (0,
|
|
6812
|
-
/* @__PURE__ */ (0,
|
|
7418
|
+
uploading && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "absolute inset-0 bg-background/80 flex items-center justify-center rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
7419
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Loader2, { className: "w-6 h-6 animate-spin text-primary" }),
|
|
7420
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-sm font-medium", children: "Uploading..." })
|
|
6813
7421
|
] }) }),
|
|
6814
|
-
/* @__PURE__ */ (0,
|
|
6815
|
-
/* @__PURE__ */ (0,
|
|
6816
|
-
/* @__PURE__ */ (0,
|
|
6817
|
-
/* @__PURE__ */ (0,
|
|
6818
|
-
/* @__PURE__ */ (0,
|
|
7422
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "space-y-4", children: [
|
|
7423
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mx-auto w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Upload, { className: "w-6 h-6 text-primary" }) }),
|
|
7424
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "space-y-2", children: [
|
|
7425
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-muted-foreground", children: dragDropText || t("dragDropText") }),
|
|
7426
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6819
7427
|
Button_default,
|
|
6820
7428
|
{
|
|
6821
7429
|
type: "button",
|
|
@@ -6827,9 +7435,9 @@ function ImageUpload({
|
|
|
6827
7435
|
}
|
|
6828
7436
|
)
|
|
6829
7437
|
] }),
|
|
6830
|
-
/* @__PURE__ */ (0,
|
|
7438
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-xs text-muted-foreground", children: supportedFormatsText || t("supportedFormats") })
|
|
6831
7439
|
] }),
|
|
6832
|
-
/* @__PURE__ */ (0,
|
|
7440
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6833
7441
|
"input",
|
|
6834
7442
|
{
|
|
6835
7443
|
ref: fileInputRef,
|
|
@@ -6844,25 +7452,25 @@ function ImageUpload({
|
|
|
6844
7452
|
]
|
|
6845
7453
|
}
|
|
6846
7454
|
),
|
|
6847
|
-
showPreview && uploadedImages.length > 0 && /* @__PURE__ */ (0,
|
|
6848
|
-
/* @__PURE__ */ (0,
|
|
6849
|
-
/* @__PURE__ */ (0,
|
|
7455
|
+
showPreview && uploadedImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "space-y-3", children: [
|
|
7456
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h4", { className: "text-sm font-medium", children: "Uploaded Images" }),
|
|
7457
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4", children: uploadedImages.map((image) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
6850
7458
|
"div",
|
|
6851
7459
|
{
|
|
6852
7460
|
className: "relative group bg-card border border-border rounded-lg p-3",
|
|
6853
7461
|
children: [
|
|
6854
|
-
/* @__PURE__ */ (0,
|
|
7462
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6855
7463
|
Button_default,
|
|
6856
7464
|
{
|
|
6857
7465
|
variant: "danger",
|
|
6858
7466
|
size: "icon",
|
|
6859
7467
|
className: "absolute -top-2 -right-2 w-6 h-6 opacity-0 group-hover:opacity-100 transition-opacity z-10",
|
|
6860
7468
|
onClick: () => handleRemoveImage(image.id),
|
|
6861
|
-
children: /* @__PURE__ */ (0,
|
|
7469
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.X, { className: "w-3 h-3" })
|
|
6862
7470
|
}
|
|
6863
7471
|
),
|
|
6864
|
-
/* @__PURE__ */ (0,
|
|
6865
|
-
/* @__PURE__ */ (0,
|
|
7472
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("mx-auto mb-2 overflow-hidden rounded-md", previewSizes[previewSize]), children: [
|
|
7473
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6866
7474
|
"img",
|
|
6867
7475
|
{
|
|
6868
7476
|
src: image.url,
|
|
@@ -6875,18 +7483,18 @@ function ImageUpload({
|
|
|
6875
7483
|
}
|
|
6876
7484
|
}
|
|
6877
7485
|
),
|
|
6878
|
-
/* @__PURE__ */ (0,
|
|
7486
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "hidden w-full h-full bg-muted flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Image, { className: "w-8 h-8 text-muted-foreground" }) })
|
|
6879
7487
|
] }),
|
|
6880
|
-
/* @__PURE__ */ (0,
|
|
6881
|
-
/* @__PURE__ */ (0,
|
|
6882
|
-
/* @__PURE__ */ (0,
|
|
6883
|
-
image.width && image.height && /* @__PURE__ */ (0,
|
|
7488
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "space-y-1", children: [
|
|
7489
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-xs font-medium truncate", title: image.originalName, children: image.originalName }),
|
|
7490
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-xs text-muted-foreground", children: image.formattedSize }),
|
|
7491
|
+
image.width && image.height && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|
|
6884
7492
|
image.width,
|
|
6885
7493
|
" \xD7 ",
|
|
6886
7494
|
image.height
|
|
6887
7495
|
] })
|
|
6888
7496
|
] }),
|
|
6889
|
-
/* @__PURE__ */ (0,
|
|
7497
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "absolute top-1 left-1 w-5 h-5 bg-success rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Check, { className: "w-3 h-3 text-success-foreground" }) })
|
|
6890
7498
|
]
|
|
6891
7499
|
},
|
|
6892
7500
|
image.id
|
|
@@ -6896,9 +7504,9 @@ function ImageUpload({
|
|
|
6896
7504
|
}
|
|
6897
7505
|
|
|
6898
7506
|
// ../../components/ui/Carousel.tsx
|
|
6899
|
-
var
|
|
6900
|
-
var
|
|
6901
|
-
var
|
|
7507
|
+
var React29 = __toESM(require("react"), 1);
|
|
7508
|
+
var import_lucide_react21 = require("lucide-react");
|
|
7509
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
6902
7510
|
function Carousel({
|
|
6903
7511
|
children,
|
|
6904
7512
|
autoScroll = true,
|
|
@@ -6919,19 +7527,19 @@ function Carousel({
|
|
|
6919
7527
|
thumbnailRenderer,
|
|
6920
7528
|
ariaLabel = "Carousel"
|
|
6921
7529
|
}) {
|
|
6922
|
-
const [currentIndex, setCurrentIndex] =
|
|
6923
|
-
const [isPaused, setIsPaused] =
|
|
6924
|
-
const [isDragging, setIsDragging] =
|
|
6925
|
-
const [startPos, setStartPos] =
|
|
6926
|
-
const [currentTranslate, setCurrentTranslate] =
|
|
6927
|
-
const [prevTranslate, setPrevTranslate] =
|
|
6928
|
-
const progressElRef =
|
|
6929
|
-
const carouselRef =
|
|
6930
|
-
const rafRef =
|
|
6931
|
-
const totalSlides =
|
|
7530
|
+
const [currentIndex, setCurrentIndex] = React29.useState(0);
|
|
7531
|
+
const [isPaused, setIsPaused] = React29.useState(false);
|
|
7532
|
+
const [isDragging, setIsDragging] = React29.useState(false);
|
|
7533
|
+
const [startPos, setStartPos] = React29.useState(0);
|
|
7534
|
+
const [currentTranslate, setCurrentTranslate] = React29.useState(0);
|
|
7535
|
+
const [prevTranslate, setPrevTranslate] = React29.useState(0);
|
|
7536
|
+
const progressElRef = React29.useRef(null);
|
|
7537
|
+
const carouselRef = React29.useRef(null);
|
|
7538
|
+
const rafRef = React29.useRef(null);
|
|
7539
|
+
const totalSlides = React29.Children.count(children);
|
|
6932
7540
|
const maxIndex = Math.max(0, totalSlides - slidesToShow);
|
|
6933
7541
|
const isHorizontal = orientation === "horizontal";
|
|
6934
|
-
const scrollPrev =
|
|
7542
|
+
const scrollPrev = React29.useCallback(() => {
|
|
6935
7543
|
setCurrentIndex((prev) => {
|
|
6936
7544
|
if (prev === 0) {
|
|
6937
7545
|
return loop ? maxIndex : 0;
|
|
@@ -6939,7 +7547,7 @@ function Carousel({
|
|
|
6939
7547
|
return Math.max(0, prev - slidesToScroll);
|
|
6940
7548
|
});
|
|
6941
7549
|
}, [loop, maxIndex, slidesToScroll]);
|
|
6942
|
-
const scrollNext =
|
|
7550
|
+
const scrollNext = React29.useCallback(() => {
|
|
6943
7551
|
setCurrentIndex((prev) => {
|
|
6944
7552
|
if (prev >= maxIndex) {
|
|
6945
7553
|
return loop ? 0 : maxIndex;
|
|
@@ -6947,13 +7555,13 @@ function Carousel({
|
|
|
6947
7555
|
return Math.min(maxIndex, prev + slidesToScroll);
|
|
6948
7556
|
});
|
|
6949
7557
|
}, [loop, maxIndex, slidesToScroll]);
|
|
6950
|
-
const scrollTo =
|
|
7558
|
+
const scrollTo = React29.useCallback(
|
|
6951
7559
|
(index) => {
|
|
6952
7560
|
setCurrentIndex(Math.min(maxIndex, Math.max(0, index)));
|
|
6953
7561
|
},
|
|
6954
7562
|
[maxIndex]
|
|
6955
7563
|
);
|
|
6956
|
-
|
|
7564
|
+
React29.useEffect(() => {
|
|
6957
7565
|
const handleKeyDown = (e) => {
|
|
6958
7566
|
if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
6959
7567
|
e.preventDefault();
|
|
@@ -6975,7 +7583,7 @@ function Carousel({
|
|
|
6975
7583
|
return () => carousel.removeEventListener("keydown", handleKeyDown);
|
|
6976
7584
|
}
|
|
6977
7585
|
}, [scrollPrev, scrollNext, scrollTo, maxIndex]);
|
|
6978
|
-
|
|
7586
|
+
React29.useEffect(() => {
|
|
6979
7587
|
const stop = () => {
|
|
6980
7588
|
if (rafRef.current != null) {
|
|
6981
7589
|
cancelAnimationFrame(rafRef.current);
|
|
@@ -7034,7 +7642,7 @@ function Carousel({
|
|
|
7034
7642
|
setCurrentTranslate(0);
|
|
7035
7643
|
setPrevTranslate(0);
|
|
7036
7644
|
};
|
|
7037
|
-
|
|
7645
|
+
React29.useEffect(() => {
|
|
7038
7646
|
onSlideChange?.(currentIndex);
|
|
7039
7647
|
}, [currentIndex, onSlideChange]);
|
|
7040
7648
|
const getAnimationStyles = () => {
|
|
@@ -7056,7 +7664,7 @@ function Carousel({
|
|
|
7056
7664
|
};
|
|
7057
7665
|
};
|
|
7058
7666
|
const slideWidth = 100 / slidesToShow;
|
|
7059
|
-
return /* @__PURE__ */ (0,
|
|
7667
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
7060
7668
|
"div",
|
|
7061
7669
|
{
|
|
7062
7670
|
ref: carouselRef,
|
|
@@ -7068,8 +7676,8 @@ function Carousel({
|
|
|
7068
7676
|
"aria-roledescription": "carousel",
|
|
7069
7677
|
tabIndex: 0,
|
|
7070
7678
|
children: [
|
|
7071
|
-
showProgress && autoScroll && /* @__PURE__ */ (0,
|
|
7072
|
-
/* @__PURE__ */ (0,
|
|
7679
|
+
showProgress && autoScroll && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "absolute top-0 left-0 right-0 h-1 bg-muted z-20", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { ref: progressElRef, className: "h-full bg-primary", style: { width: "0%" } }) }),
|
|
7680
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7073
7681
|
"div",
|
|
7074
7682
|
{
|
|
7075
7683
|
className: cn("flex", isHorizontal ? "flex-row" : "flex-col", containerClassName),
|
|
@@ -7084,7 +7692,7 @@ function Carousel({
|
|
|
7084
7692
|
role: "group",
|
|
7085
7693
|
"aria-atomic": "false",
|
|
7086
7694
|
"aria-live": autoScroll ? "off" : "polite",
|
|
7087
|
-
children:
|
|
7695
|
+
children: React29.Children.map(children, (child, idx) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7088
7696
|
"div",
|
|
7089
7697
|
{
|
|
7090
7698
|
className: cn(
|
|
@@ -7107,14 +7715,14 @@ function Carousel({
|
|
|
7107
7715
|
))
|
|
7108
7716
|
}
|
|
7109
7717
|
),
|
|
7110
|
-
showArrows && totalSlides > slidesToShow && /* @__PURE__ */ (0,
|
|
7111
|
-
/* @__PURE__ */ (0,
|
|
7718
|
+
showArrows && totalSlides > slidesToShow && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
7719
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7112
7720
|
Button_default,
|
|
7113
7721
|
{
|
|
7114
7722
|
onClick: scrollPrev,
|
|
7115
7723
|
variant: "ghost",
|
|
7116
7724
|
size: "icon",
|
|
7117
|
-
icon:
|
|
7725
|
+
icon: import_lucide_react21.ChevronLeft,
|
|
7118
7726
|
noHoverOverlay: true,
|
|
7119
7727
|
disabled: !loop && currentIndex === 0,
|
|
7120
7728
|
className: cn(
|
|
@@ -7124,13 +7732,13 @@ function Carousel({
|
|
|
7124
7732
|
"aria-label": "Previous slide"
|
|
7125
7733
|
}
|
|
7126
7734
|
),
|
|
7127
|
-
/* @__PURE__ */ (0,
|
|
7735
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7128
7736
|
Button_default,
|
|
7129
7737
|
{
|
|
7130
7738
|
onClick: scrollNext,
|
|
7131
7739
|
variant: "ghost",
|
|
7132
7740
|
size: "icon",
|
|
7133
|
-
icon:
|
|
7741
|
+
icon: import_lucide_react21.ChevronRight,
|
|
7134
7742
|
noHoverOverlay: true,
|
|
7135
7743
|
disabled: !loop && currentIndex >= maxIndex,
|
|
7136
7744
|
className: cn(
|
|
@@ -7141,7 +7749,7 @@ function Carousel({
|
|
|
7141
7749
|
}
|
|
7142
7750
|
)
|
|
7143
7751
|
] }),
|
|
7144
|
-
showDots && totalSlides > slidesToShow && /* @__PURE__ */ (0,
|
|
7752
|
+
showDots && totalSlides > slidesToShow && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7145
7753
|
"div",
|
|
7146
7754
|
{
|
|
7147
7755
|
className: cn(
|
|
@@ -7150,7 +7758,7 @@ function Carousel({
|
|
|
7150
7758
|
),
|
|
7151
7759
|
role: "tablist",
|
|
7152
7760
|
"aria-label": "Carousel pagination",
|
|
7153
|
-
children: Array.from({ length: maxIndex + 1 }, (_, idx) => /* @__PURE__ */ (0,
|
|
7761
|
+
children: Array.from({ length: maxIndex + 1 }, (_, idx) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7154
7762
|
"button",
|
|
7155
7763
|
{
|
|
7156
7764
|
onClick: () => scrollTo(idx),
|
|
@@ -7167,14 +7775,14 @@ function Carousel({
|
|
|
7167
7775
|
))
|
|
7168
7776
|
}
|
|
7169
7777
|
),
|
|
7170
|
-
showThumbnails && totalSlides > slidesToShow && /* @__PURE__ */ (0,
|
|
7778
|
+
showThumbnails && totalSlides > slidesToShow && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7171
7779
|
"div",
|
|
7172
7780
|
{
|
|
7173
7781
|
className: cn(
|
|
7174
7782
|
"absolute bottom-0 left-0 right-0 flex gap-2 p-4 bg-gradient-to-t from-black/50 to-transparent overflow-x-auto",
|
|
7175
7783
|
isHorizontal ? "flex-row" : "flex-col"
|
|
7176
7784
|
),
|
|
7177
|
-
children:
|
|
7785
|
+
children: React29.Children.map(children, (child, idx) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7178
7786
|
"button",
|
|
7179
7787
|
{
|
|
7180
7788
|
onClick: () => scrollTo(idx),
|
|
@@ -7196,7 +7804,7 @@ function Carousel({
|
|
|
7196
7804
|
|
|
7197
7805
|
// ../../components/ui/FallingIcons.tsx
|
|
7198
7806
|
var import_react19 = __toESM(require("react"), 1);
|
|
7199
|
-
var
|
|
7807
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
7200
7808
|
var DEFAULT_COUNT = 24;
|
|
7201
7809
|
var DEFAULT_SPEED_RANGE = [6, 14];
|
|
7202
7810
|
var DEFAULT_SIZE_RANGE = [14, 28];
|
|
@@ -7291,8 +7899,8 @@ function FallingIcons({
|
|
|
7291
7899
|
filter: `drop-shadow(0 0 ${4 * intensity}px ${glowColor}) drop-shadow(0 0 ${8 * intensity}px ${glowColor})`
|
|
7292
7900
|
};
|
|
7293
7901
|
}, [glow, glowColor, glowIntensity]);
|
|
7294
|
-
const FallbackIcon = import_react19.default.useMemo(() => (props) => /* @__PURE__ */ (0,
|
|
7295
|
-
const TheIcon = imageUrl ? ({ className: imgClassName }) => /* @__PURE__ */ (0,
|
|
7902
|
+
const FallbackIcon = import_react19.default.useMemo(() => (props) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("circle", { cx: "12", cy: "12", r: "10" }) }), []);
|
|
7903
|
+
const TheIcon = imageUrl ? ({ className: imgClassName }) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7296
7904
|
"img",
|
|
7297
7905
|
{
|
|
7298
7906
|
src: imageUrl,
|
|
@@ -7301,7 +7909,7 @@ function FallingIcons({
|
|
|
7301
7909
|
draggable: false
|
|
7302
7910
|
}
|
|
7303
7911
|
) : Icon || FallbackIcon;
|
|
7304
|
-
return /* @__PURE__ */ (0,
|
|
7912
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
7305
7913
|
"div",
|
|
7306
7914
|
{
|
|
7307
7915
|
ref: containerRef,
|
|
@@ -7311,7 +7919,7 @@ function FallingIcons({
|
|
|
7311
7919
|
),
|
|
7312
7920
|
style: { zIndex },
|
|
7313
7921
|
children: [
|
|
7314
|
-
/* @__PURE__ */ (0,
|
|
7922
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("style", { children: `
|
|
7315
7923
|
@keyframes ${FallName} {
|
|
7316
7924
|
0% { transform: translate3d(0, -10vh, 0); opacity: 0; }
|
|
7317
7925
|
10% { opacity: 1; }
|
|
@@ -7344,7 +7952,7 @@ function FallingIcons({
|
|
|
7344
7952
|
}
|
|
7345
7953
|
}
|
|
7346
7954
|
` }),
|
|
7347
|
-
/* @__PURE__ */ (0,
|
|
7955
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7348
7956
|
"div",
|
|
7349
7957
|
{
|
|
7350
7958
|
className: cn(
|
|
@@ -7365,12 +7973,12 @@ function FallingIcons({
|
|
|
7365
7973
|
});
|
|
7366
7974
|
};
|
|
7367
7975
|
const trailParticles = trail ? Array.from({ length: Math.min(5, Math.max(1, trailLength)) }) : [];
|
|
7368
|
-
return /* @__PURE__ */ (0,
|
|
7976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react19.default.Fragment, { children: [
|
|
7369
7977
|
trail && trailParticles.map((_, trailIndex) => {
|
|
7370
7978
|
const trailDelay = p.delay - (trailIndex + 1) * 0.15;
|
|
7371
7979
|
const trailOpacity = 1 - (trailIndex + 1) * (1 / (trailParticles.length + 1));
|
|
7372
7980
|
const trailScale = 1 - (trailIndex + 1) * 0.15;
|
|
7373
|
-
return /* @__PURE__ */ (0,
|
|
7981
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7374
7982
|
"span",
|
|
7375
7983
|
{
|
|
7376
7984
|
className: cn("absolute top-0 will-change-transform pointer-events-none uv-falling-particle", colorClassName),
|
|
@@ -7384,7 +7992,7 @@ function FallingIcons({
|
|
|
7384
7992
|
opacity: trailOpacity * 0.4,
|
|
7385
7993
|
["--fall"]: `${fallDist ?? (typeof window !== "undefined" ? window.innerHeight + 200 : 1200)}px`
|
|
7386
7994
|
},
|
|
7387
|
-
children: /* @__PURE__ */ (0,
|
|
7995
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7388
7996
|
"span",
|
|
7389
7997
|
{
|
|
7390
7998
|
className: "inline-block uv-sway",
|
|
@@ -7396,7 +8004,7 @@ function FallingIcons({
|
|
|
7396
8004
|
animationIterationCount: "infinite",
|
|
7397
8005
|
["--amp"]: `${Math.round(p.driftAmp)}px`
|
|
7398
8006
|
},
|
|
7399
|
-
children: /* @__PURE__ */ (0,
|
|
8007
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7400
8008
|
"span",
|
|
7401
8009
|
{
|
|
7402
8010
|
className: "block",
|
|
@@ -7405,7 +8013,7 @@ function FallingIcons({
|
|
|
7405
8013
|
height: p.size,
|
|
7406
8014
|
...glowStyles
|
|
7407
8015
|
},
|
|
7408
|
-
children: /* @__PURE__ */ (0,
|
|
8016
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(TheIcon, { className: cn("w-full h-full text-primary/70", colorClassName) })
|
|
7409
8017
|
}
|
|
7410
8018
|
)
|
|
7411
8019
|
}
|
|
@@ -7414,7 +8022,7 @@ function FallingIcons({
|
|
|
7414
8022
|
`${p.key}-trail-${trailIndex}`
|
|
7415
8023
|
);
|
|
7416
8024
|
}),
|
|
7417
|
-
/* @__PURE__ */ (0,
|
|
8025
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7418
8026
|
"span",
|
|
7419
8027
|
{
|
|
7420
8028
|
className: cn("absolute top-0 will-change-transform pointer-events-auto uv-falling-particle", colorClassName),
|
|
@@ -7440,7 +8048,7 @@ function FallingIcons({
|
|
|
7440
8048
|
return next;
|
|
7441
8049
|
});
|
|
7442
8050
|
},
|
|
7443
|
-
children: /* @__PURE__ */ (0,
|
|
8051
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7444
8052
|
"span",
|
|
7445
8053
|
{
|
|
7446
8054
|
className: "inline-block uv-sway",
|
|
@@ -7452,7 +8060,7 @@ function FallingIcons({
|
|
|
7452
8060
|
animationIterationCount: "infinite",
|
|
7453
8061
|
["--amp"]: `${Math.round(p.driftAmp)}px`
|
|
7454
8062
|
},
|
|
7455
|
-
children: /* @__PURE__ */ (0,
|
|
8063
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7456
8064
|
"span",
|
|
7457
8065
|
{
|
|
7458
8066
|
className: cn(
|
|
@@ -7468,7 +8076,7 @@ function FallingIcons({
|
|
|
7468
8076
|
["--popName"]: PopName,
|
|
7469
8077
|
...glowStyles
|
|
7470
8078
|
},
|
|
7471
|
-
children: /* @__PURE__ */ (0,
|
|
8079
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(TheIcon, { className: cn("w-full h-full text-primary/70", colorClassName) })
|
|
7472
8080
|
}
|
|
7473
8081
|
)
|
|
7474
8082
|
}
|
|
@@ -7484,23 +8092,1340 @@ function FallingIcons({
|
|
|
7484
8092
|
);
|
|
7485
8093
|
}
|
|
7486
8094
|
|
|
8095
|
+
// ../../components/ui/List.tsx
|
|
8096
|
+
var React31 = __toESM(require("react"), 1);
|
|
8097
|
+
var import_lucide_react22 = require("lucide-react");
|
|
8098
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
8099
|
+
var SIZE_STYLES2 = {
|
|
8100
|
+
xs: { itemPad: "px-2 py-1.5", densePad: "px-2 py-1", label: "text-xs", desc: "text-[11px]", icon: "h-3.5 w-3.5", avatar: "h-6 w-6" },
|
|
8101
|
+
sm: { itemPad: "px-3 py-2", densePad: "px-3 py-1.5", label: "text-[13px]", desc: "text-[12px]", icon: "h-4 w-4", avatar: "h-8 w-8" },
|
|
8102
|
+
md: { itemPad: "px-4 py-2.5", densePad: "px-4 py-2", label: "text-sm", desc: "text-xs", icon: "h-5 w-5", avatar: "h-10 w-10" },
|
|
8103
|
+
lg: { itemPad: "px-5 py-3", densePad: "px-5 py-2.5", label: "text-base", desc: "text-sm", icon: "h-5 w-5", avatar: "h-12 w-12" }
|
|
8104
|
+
};
|
|
8105
|
+
var BADGE_VARIANTS = {
|
|
8106
|
+
default: "bg-muted text-muted-foreground",
|
|
8107
|
+
success: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
8108
|
+
warning: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400",
|
|
8109
|
+
error: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
|
|
8110
|
+
info: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"
|
|
8111
|
+
};
|
|
8112
|
+
var ListItemSkeleton = ({ size }) => {
|
|
8113
|
+
const sz = SIZE_STYLES2[size];
|
|
8114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("flex items-center gap-3 animate-pulse", sz.itemPad), children: [
|
|
8115
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("rounded-full bg-muted shrink-0", sz.avatar) }),
|
|
8116
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex-1 space-y-2", children: [
|
|
8117
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "h-4 bg-muted rounded w-3/4" }),
|
|
8118
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "h-3 bg-muted rounded w-1/2" })
|
|
8119
|
+
] })
|
|
8120
|
+
] });
|
|
8121
|
+
};
|
|
8122
|
+
var ListRoot = React31.forwardRef(
|
|
8123
|
+
({
|
|
8124
|
+
as = "ul",
|
|
8125
|
+
ordered,
|
|
8126
|
+
variant = "plain",
|
|
8127
|
+
size = "md",
|
|
8128
|
+
divided = false,
|
|
8129
|
+
inset = false,
|
|
8130
|
+
hoverable = true,
|
|
8131
|
+
loading: loading2 = false,
|
|
8132
|
+
loadingCount = 3,
|
|
8133
|
+
emptyText,
|
|
8134
|
+
dense = false,
|
|
8135
|
+
className,
|
|
8136
|
+
children,
|
|
8137
|
+
...rest
|
|
8138
|
+
}, ref) => {
|
|
8139
|
+
const Comp = ordered ? "ol" : as;
|
|
8140
|
+
const childCount = React31.Children.count(children);
|
|
8141
|
+
const hasChildren = childCount > 0;
|
|
8142
|
+
const variantClasses = {
|
|
8143
|
+
plain: "",
|
|
8144
|
+
outlined: "rounded-lg md:rounded-xl bg-card text-card-foreground border border-border shadow-sm",
|
|
8145
|
+
soft: "rounded-lg bg-muted/40 border border-border/60",
|
|
8146
|
+
bordered: "border border-border rounded-lg",
|
|
8147
|
+
card: "rounded-lg bg-card shadow-md border border-border",
|
|
8148
|
+
flush: "",
|
|
8149
|
+
striped: "rounded-lg border border-border overflow-hidden"
|
|
8150
|
+
};
|
|
8151
|
+
if (loading2) {
|
|
8152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Comp, { ref, className: cn("group/list", variantClasses[variant], inset && "p-1.5 md:p-2", divided && "divide-y divide-border/60", className), ...rest, children: Array.from({ length: loadingCount }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ListItemSkeleton, { size }, i)) });
|
|
8153
|
+
}
|
|
8154
|
+
if (!hasChildren && emptyText) {
|
|
8155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Comp, { ref, className: cn("group/list", variantClasses[variant], inset && "p-1.5 md:p-2", className), ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "text-center py-8 text-muted-foreground text-sm", children: emptyText }) });
|
|
8156
|
+
}
|
|
8157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8158
|
+
Comp,
|
|
8159
|
+
{
|
|
8160
|
+
ref,
|
|
8161
|
+
className: cn(
|
|
8162
|
+
"group/list",
|
|
8163
|
+
variantClasses[variant],
|
|
8164
|
+
inset && "p-1.5 md:p-2",
|
|
8165
|
+
divided && "divide-y divide-border/60",
|
|
8166
|
+
variant === "striped" && "[&>*:nth-child(even)]:bg-muted/30",
|
|
8167
|
+
className
|
|
8168
|
+
),
|
|
8169
|
+
...rest,
|
|
8170
|
+
children: React31.Children.map(children, (child, idx) => {
|
|
8171
|
+
if (!React31.isValidElement(child)) return child;
|
|
8172
|
+
const childClass = cn(
|
|
8173
|
+
child.props?.className,
|
|
8174
|
+
hoverable && variant !== "flush" && "hover:bg-accent/50 focus:bg-accent/60 focus:outline-none transition-colors",
|
|
8175
|
+
variant === "flush" && "hover:bg-accent/30"
|
|
8176
|
+
);
|
|
8177
|
+
return React31.cloneElement(child, {
|
|
8178
|
+
className: childClass,
|
|
8179
|
+
"data-first": idx === 0 ? "true" : void 0,
|
|
8180
|
+
"data-last": idx === childCount - 1 ? "true" : void 0,
|
|
8181
|
+
"data-size": size,
|
|
8182
|
+
"data-dense": dense ? "true" : void 0
|
|
8183
|
+
});
|
|
8184
|
+
})
|
|
8185
|
+
}
|
|
8186
|
+
);
|
|
8187
|
+
}
|
|
8188
|
+
);
|
|
8189
|
+
ListRoot.displayName = "List";
|
|
8190
|
+
var ListItem = React31.forwardRef(
|
|
8191
|
+
({
|
|
8192
|
+
as = "li",
|
|
8193
|
+
selected = false,
|
|
8194
|
+
disabled = false,
|
|
8195
|
+
href,
|
|
8196
|
+
label,
|
|
8197
|
+
description,
|
|
8198
|
+
leftIcon: Left,
|
|
8199
|
+
rightIcon: Right,
|
|
8200
|
+
avatar,
|
|
8201
|
+
badge,
|
|
8202
|
+
badgeVariant = "default",
|
|
8203
|
+
action,
|
|
8204
|
+
collapsible = false,
|
|
8205
|
+
expanded: controlledExpanded,
|
|
8206
|
+
onExpandChange,
|
|
8207
|
+
expandContent,
|
|
8208
|
+
className,
|
|
8209
|
+
children,
|
|
8210
|
+
...rest
|
|
8211
|
+
}, ref) => {
|
|
8212
|
+
const [internalExpanded, setInternalExpanded] = React31.useState(false);
|
|
8213
|
+
const isExpanded = controlledExpanded !== void 0 ? controlledExpanded : internalExpanded;
|
|
8214
|
+
const sizeAttr = rest["data-size"];
|
|
8215
|
+
const denseAttr = rest["data-dense"];
|
|
8216
|
+
const isDense = denseAttr === "true";
|
|
8217
|
+
const resolvedSize = sizeAttr && (sizeAttr === "xs" || sizeAttr === "sm" || sizeAttr === "md" || sizeAttr === "lg") ? sizeAttr : "md";
|
|
8218
|
+
const sz = SIZE_STYLES2[resolvedSize];
|
|
8219
|
+
const padding = isDense ? sz.densePad : sz.itemPad;
|
|
8220
|
+
const toggleExpanded = () => {
|
|
8221
|
+
const newExpanded = !isExpanded;
|
|
8222
|
+
if (onExpandChange) {
|
|
8223
|
+
onExpandChange(newExpanded);
|
|
8224
|
+
} else {
|
|
8225
|
+
setInternalExpanded(newExpanded);
|
|
8226
|
+
}
|
|
8227
|
+
};
|
|
8228
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
|
|
8229
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("flex items-center gap-3", padding, "group/item relative"), children: [
|
|
8230
|
+
avatar && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("shrink-0", sz.avatar), children: typeof avatar === "string" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("img", { src: avatar, alt: "", className: cn("rounded-full object-cover", sz.avatar) }) : avatar }),
|
|
8231
|
+
Left && !avatar && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("text-muted-foreground shrink-0", sz.icon), children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Left, { className: cn(sz.icon) }) }),
|
|
8232
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
8233
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8234
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn(sz.label, "text-foreground font-medium truncate"), children: label }),
|
|
8235
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("px-2 py-0.5 rounded-full text-[11px] font-medium shrink-0", BADGE_VARIANTS[badgeVariant]), children: badge })
|
|
8236
|
+
] }),
|
|
8237
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn(sz.desc, "text-muted-foreground truncate mt-0.5"), children: description }),
|
|
8238
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "mt-1", children })
|
|
8239
|
+
] }),
|
|
8240
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "opacity-0 group-hover/item:opacity-100 transition-opacity shrink-0", children: action }),
|
|
8241
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8242
|
+
"span",
|
|
8243
|
+
{
|
|
8244
|
+
role: "button",
|
|
8245
|
+
"aria-label": "Toggle",
|
|
8246
|
+
tabIndex: 0,
|
|
8247
|
+
onClick: (e) => {
|
|
8248
|
+
e.stopPropagation();
|
|
8249
|
+
toggleExpanded();
|
|
8250
|
+
},
|
|
8251
|
+
onKeyDown: (e) => {
|
|
8252
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8253
|
+
e.preventDefault();
|
|
8254
|
+
e.stopPropagation();
|
|
8255
|
+
toggleExpanded();
|
|
8256
|
+
}
|
|
8257
|
+
},
|
|
8258
|
+
className: cn("text-muted-foreground shrink-0 transition-transform cursor-pointer select-none", sz.icon, isExpanded && "rotate-90"),
|
|
8259
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react22.ChevronRight, { className: cn(sz.icon) })
|
|
8260
|
+
}
|
|
8261
|
+
) : Right && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("text-muted-foreground shrink-0", sz.icon), children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Right, { className: cn(sz.icon) }) })
|
|
8262
|
+
] }),
|
|
8263
|
+
collapsible && isExpanded && expandContent && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("border-t border-border/50 bg-muted/20", padding, "pt-3"), children: expandContent })
|
|
8264
|
+
] });
|
|
8265
|
+
const baseCls = cn(
|
|
8266
|
+
"relative w-full",
|
|
8267
|
+
selected && "bg-primary/10 ring-1 ring-primary/30",
|
|
8268
|
+
disabled && "opacity-60 cursor-not-allowed",
|
|
8269
|
+
className
|
|
8270
|
+
);
|
|
8271
|
+
if (href) {
|
|
8272
|
+
const A = as === "a" ? "a" : "a";
|
|
8273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(A, { ref, href, className: cn(baseCls, "block"), ...rest, children: inner });
|
|
8274
|
+
}
|
|
8275
|
+
if (as === "button" || collapsible) {
|
|
8276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
8277
|
+
"button",
|
|
8278
|
+
{
|
|
8279
|
+
ref,
|
|
8280
|
+
type: "button",
|
|
8281
|
+
className: cn(baseCls, "text-left block w-full"),
|
|
8282
|
+
onClick: collapsible ? toggleExpanded : void 0,
|
|
8283
|
+
...rest,
|
|
8284
|
+
children: inner
|
|
8285
|
+
}
|
|
8286
|
+
);
|
|
8287
|
+
}
|
|
8288
|
+
const Comp = as;
|
|
8289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Comp, { ref, className: baseCls, ...rest, children: inner });
|
|
8290
|
+
}
|
|
8291
|
+
);
|
|
8292
|
+
ListItem.displayName = "List.Item";
|
|
8293
|
+
var List = Object.assign(ListRoot, { Item: ListItem });
|
|
8294
|
+
var List_default = List;
|
|
8295
|
+
|
|
8296
|
+
// ../../components/ui/Watermark.tsx
|
|
8297
|
+
var React32 = __toESM(require("react"), 1);
|
|
8298
|
+
var import_react_dom9 = require("react-dom");
|
|
8299
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
8300
|
+
var PRESETS2 = {
|
|
8301
|
+
confidential: { text: "CONFIDENTIAL", color: "rgba(220, 38, 38, 0.15)", rotate: -22, fontSize: 16, fontWeight: "bold" },
|
|
8302
|
+
draft: { text: "DRAFT", color: "rgba(59, 130, 246, 0.15)", rotate: -22, fontSize: 18, fontWeight: "bold" },
|
|
8303
|
+
sample: { text: "SAMPLE", color: "rgba(168, 85, 247, 0.15)", rotate: -22, fontSize: 16, fontWeight: "600" },
|
|
8304
|
+
copyright: { text: "\xA9 Copyright", color: "rgba(0, 0, 0, 0.1)", rotate: 0, fontSize: 12, fontWeight: "normal" },
|
|
8305
|
+
doNotCopy: { text: "DO NOT COPY", color: "rgba(234, 88, 12, 0.15)", rotate: -22, fontSize: 14, fontWeight: "bold" },
|
|
8306
|
+
internal: { text: "INTERNAL USE ONLY", color: "rgba(156, 163, 175, 0.15)", rotate: -22, fontSize: 13, fontWeight: "600" }
|
|
8307
|
+
};
|
|
8308
|
+
function useWatermarkDataURL(opts) {
|
|
8309
|
+
const [url, setUrl] = React32.useState(null);
|
|
8310
|
+
React32.useEffect(() => {
|
|
8311
|
+
let cancelled = false;
|
|
8312
|
+
const text = opts.text;
|
|
8313
|
+
const image = opts.image;
|
|
8314
|
+
const width = opts.width ?? 180;
|
|
8315
|
+
const height = opts.height ?? 100;
|
|
8316
|
+
const gapX = opts.gapX ?? 16;
|
|
8317
|
+
const gapY = opts.gapY ?? 16;
|
|
8318
|
+
const rotate = opts.rotate ?? -22;
|
|
8319
|
+
const fontSize = opts.fontSize ?? 14;
|
|
8320
|
+
const fontFamily = opts.fontFamily ?? "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial";
|
|
8321
|
+
const fontWeight = opts.fontWeight ?? "normal";
|
|
8322
|
+
const fontStyle = opts.fontStyle ?? "normal";
|
|
8323
|
+
const color = opts.color ?? "rgba(0,0,0,0.15)";
|
|
8324
|
+
const gradient = opts.gradient;
|
|
8325
|
+
const pattern = opts.pattern ?? "diagonal";
|
|
8326
|
+
const tileW = width + gapX;
|
|
8327
|
+
const tileH = height + gapY;
|
|
8328
|
+
const canvas = document.createElement("canvas");
|
|
8329
|
+
canvas.width = tileW;
|
|
8330
|
+
canvas.height = tileH;
|
|
8331
|
+
const ctx = canvas.getContext("2d");
|
|
8332
|
+
if (!ctx) return;
|
|
8333
|
+
const drawText = () => {
|
|
8334
|
+
ctx.clearRect(0, 0, tileW, tileH);
|
|
8335
|
+
ctx.save();
|
|
8336
|
+
ctx.translate(tileW / 2, tileH / 2);
|
|
8337
|
+
if (pattern === "diagonal") {
|
|
8338
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
8339
|
+
} else if (pattern === "straight") {
|
|
8340
|
+
}
|
|
8341
|
+
if (text) {
|
|
8342
|
+
const textLines = Array.isArray(text) ? text : [text];
|
|
8343
|
+
ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
8344
|
+
ctx.textAlign = "center";
|
|
8345
|
+
ctx.textBaseline = "middle";
|
|
8346
|
+
if (gradient) {
|
|
8347
|
+
const splitStops = (input) => {
|
|
8348
|
+
const s = input.trim();
|
|
8349
|
+
let inside = s;
|
|
8350
|
+
const lg = s.toLowerCase();
|
|
8351
|
+
if (lg.startsWith("linear-gradient")) {
|
|
8352
|
+
const start = s.indexOf("(");
|
|
8353
|
+
const end = s.lastIndexOf(")");
|
|
8354
|
+
if (start >= 0 && end > start) inside = s.slice(start + 1, end);
|
|
8355
|
+
}
|
|
8356
|
+
const parts = [];
|
|
8357
|
+
let buf = "";
|
|
8358
|
+
let depth = 0;
|
|
8359
|
+
for (let i = 0; i < inside.length; i++) {
|
|
8360
|
+
const ch = inside[i];
|
|
8361
|
+
if (ch === "(") depth++;
|
|
8362
|
+
if (ch === ")") depth = Math.max(0, depth - 1);
|
|
8363
|
+
if (ch === "," && depth === 0) {
|
|
8364
|
+
parts.push(buf.trim());
|
|
8365
|
+
buf = "";
|
|
8366
|
+
} else {
|
|
8367
|
+
buf += ch;
|
|
8368
|
+
}
|
|
8369
|
+
}
|
|
8370
|
+
if (buf.trim()) parts.push(buf.trim());
|
|
8371
|
+
if (parts.length > 0) {
|
|
8372
|
+
const first = parts[0].toLowerCase();
|
|
8373
|
+
if (first.startsWith("to ") || first.endsWith("deg") || first.endsWith("rad")) {
|
|
8374
|
+
parts.shift();
|
|
8375
|
+
}
|
|
8376
|
+
}
|
|
8377
|
+
return parts.filter(Boolean);
|
|
8378
|
+
};
|
|
8379
|
+
const stops = splitStops(gradient);
|
|
8380
|
+
const gradientObj = ctx.createLinearGradient(0, -height / 2, 0, height / 2);
|
|
8381
|
+
stops.forEach((c, i) => {
|
|
8382
|
+
const tokens = c.split(/\s+/).filter(Boolean);
|
|
8383
|
+
const col = tokens[0];
|
|
8384
|
+
const pos = tokens[1] ? parseFloat(tokens[1]) / 100 : i / Math.max(1, stops.length - 1);
|
|
8385
|
+
try {
|
|
8386
|
+
gradientObj.addColorStop(isFinite(pos) ? Math.min(Math.max(pos, 0), 1) : i / Math.max(1, stops.length - 1), col);
|
|
8387
|
+
} catch {
|
|
8388
|
+
}
|
|
8389
|
+
});
|
|
8390
|
+
ctx.fillStyle = gradientObj;
|
|
8391
|
+
} else {
|
|
8392
|
+
ctx.fillStyle = color;
|
|
8393
|
+
}
|
|
8394
|
+
const lineHeight = fontSize * 1.2;
|
|
8395
|
+
const totalHeight = textLines.length * lineHeight;
|
|
8396
|
+
const startY = -(totalHeight / 2) + lineHeight / 2;
|
|
8397
|
+
textLines.forEach((line, index) => {
|
|
8398
|
+
const y = startY + index * lineHeight;
|
|
8399
|
+
ctx.fillText(line, 0, y, width);
|
|
8400
|
+
});
|
|
8401
|
+
}
|
|
8402
|
+
ctx.restore();
|
|
8403
|
+
if (!cancelled) setUrl(canvas.toDataURL());
|
|
8404
|
+
};
|
|
8405
|
+
if (image) {
|
|
8406
|
+
const img = new Image();
|
|
8407
|
+
img.crossOrigin = "anonymous";
|
|
8408
|
+
img.onload = () => {
|
|
8409
|
+
ctx.clearRect(0, 0, tileW, tileH);
|
|
8410
|
+
ctx.save();
|
|
8411
|
+
ctx.translate(tileW / 2, tileH / 2);
|
|
8412
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
8413
|
+
const drawW = width;
|
|
8414
|
+
const drawH = height;
|
|
8415
|
+
ctx.drawImage(img, -drawW / 2, -drawH / 2, drawW, drawH);
|
|
8416
|
+
ctx.restore();
|
|
8417
|
+
if (!cancelled) setUrl(canvas.toDataURL());
|
|
8418
|
+
};
|
|
8419
|
+
img.onerror = drawText;
|
|
8420
|
+
img.src = image;
|
|
8421
|
+
} else {
|
|
8422
|
+
drawText();
|
|
8423
|
+
}
|
|
8424
|
+
return () => {
|
|
8425
|
+
cancelled = true;
|
|
8426
|
+
};
|
|
8427
|
+
}, [opts.text, opts.image, opts.width, opts.height, opts.gapX, opts.gapY, opts.rotate, opts.fontSize, opts.fontFamily, opts.fontWeight, opts.fontStyle, opts.color, opts.gradient, opts.pattern]);
|
|
8428
|
+
return url;
|
|
8429
|
+
}
|
|
8430
|
+
var Watermark = ({
|
|
8431
|
+
text: textProp,
|
|
8432
|
+
image,
|
|
8433
|
+
width = 180,
|
|
8434
|
+
height = 100,
|
|
8435
|
+
gapX = 16,
|
|
8436
|
+
gapY = 16,
|
|
8437
|
+
rotate: rotateProp,
|
|
8438
|
+
fontSize: fontSizeProp,
|
|
8439
|
+
fontFamily = "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial",
|
|
8440
|
+
fontWeight: fontWeightProp,
|
|
8441
|
+
fontStyle: fontStyleProp,
|
|
8442
|
+
color: colorProp,
|
|
8443
|
+
gradient,
|
|
8444
|
+
opacity = 1,
|
|
8445
|
+
offsetLeft = 0,
|
|
8446
|
+
offsetTop = 0,
|
|
8447
|
+
zIndex = 40,
|
|
8448
|
+
fullPage = false,
|
|
8449
|
+
preset,
|
|
8450
|
+
pattern = "diagonal",
|
|
8451
|
+
interactive = false,
|
|
8452
|
+
animate = false,
|
|
8453
|
+
overlayClassName,
|
|
8454
|
+
className,
|
|
8455
|
+
style,
|
|
8456
|
+
children,
|
|
8457
|
+
...rest
|
|
8458
|
+
}) => {
|
|
8459
|
+
const [visible, setVisible] = React32.useState(true);
|
|
8460
|
+
const presetConfig = preset ? PRESETS2[preset] : null;
|
|
8461
|
+
const text = textProp ?? presetConfig?.text;
|
|
8462
|
+
const color = colorProp ?? presetConfig?.color ?? "rgba(0,0,0,0.15)";
|
|
8463
|
+
const rotate = rotateProp ?? presetConfig?.rotate ?? -22;
|
|
8464
|
+
const fontSize = fontSizeProp ?? presetConfig?.fontSize ?? 14;
|
|
8465
|
+
const fontWeight = fontWeightProp ?? presetConfig?.fontWeight ?? "normal";
|
|
8466
|
+
const fontStyle = fontStyleProp ?? "normal";
|
|
8467
|
+
const dataURL = useWatermarkDataURL({
|
|
8468
|
+
text,
|
|
8469
|
+
image,
|
|
8470
|
+
width,
|
|
8471
|
+
height,
|
|
8472
|
+
gapX,
|
|
8473
|
+
gapY,
|
|
8474
|
+
rotate,
|
|
8475
|
+
fontSize,
|
|
8476
|
+
fontFamily,
|
|
8477
|
+
fontWeight,
|
|
8478
|
+
fontStyle,
|
|
8479
|
+
color,
|
|
8480
|
+
gradient,
|
|
8481
|
+
pattern
|
|
8482
|
+
});
|
|
8483
|
+
const overlayStyle = {
|
|
8484
|
+
position: fullPage ? "fixed" : "absolute",
|
|
8485
|
+
top: 0,
|
|
8486
|
+
left: 0,
|
|
8487
|
+
zIndex,
|
|
8488
|
+
opacity: visible ? opacity : 0,
|
|
8489
|
+
backgroundRepeat: "repeat",
|
|
8490
|
+
backgroundPosition: `${offsetLeft}px ${offsetTop}px`,
|
|
8491
|
+
transition: animate ? "opacity 0.3s ease" : void 0
|
|
8492
|
+
};
|
|
8493
|
+
if (fullPage) {
|
|
8494
|
+
overlayStyle.right = 0;
|
|
8495
|
+
overlayStyle.bottom = 0;
|
|
8496
|
+
} else {
|
|
8497
|
+
overlayStyle.width = "100%";
|
|
8498
|
+
overlayStyle.height = "100%";
|
|
8499
|
+
}
|
|
8500
|
+
if (dataURL) overlayStyle.backgroundImage = `url(${dataURL})`;
|
|
8501
|
+
const overlay = /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
8502
|
+
"div",
|
|
8503
|
+
{
|
|
8504
|
+
"aria-hidden": true,
|
|
8505
|
+
className: cn("pointer-events-none", overlayClassName),
|
|
8506
|
+
style: overlayStyle,
|
|
8507
|
+
onClick: interactive ? () => setVisible(!visible) : void 0
|
|
8508
|
+
}
|
|
8509
|
+
);
|
|
8510
|
+
if (fullPage) {
|
|
8511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
8512
|
+
children,
|
|
8513
|
+
typeof window !== "undefined" ? (0, import_react_dom9.createPortal)(overlay, document.body) : null
|
|
8514
|
+
] });
|
|
8515
|
+
}
|
|
8516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("relative", className), style, ...rest, children: [
|
|
8517
|
+
children,
|
|
8518
|
+
overlay
|
|
8519
|
+
] });
|
|
8520
|
+
};
|
|
8521
|
+
var Watermark_default = Watermark;
|
|
8522
|
+
|
|
8523
|
+
// ../../components/ui/Timeline.tsx
|
|
8524
|
+
var React33 = __toESM(require("react"), 1);
|
|
8525
|
+
var import_lucide_react23 = require("lucide-react");
|
|
8526
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8527
|
+
var SIZE_STYLE = {
|
|
8528
|
+
sm: { dot: "h-2.5 w-2.5", iconDot: "h-6 w-6", padY: "py-3", densePadY: "py-2", title: "text-sm", desc: "text-xs", time: "text-[11px]", icon: "h-3.5 w-3.5" },
|
|
8529
|
+
md: { dot: "h-3 w-3", iconDot: "h-8 w-8", padY: "py-4", densePadY: "py-2.5", title: "text-base", desc: "text-sm", time: "text-xs", icon: "h-4 w-4" },
|
|
8530
|
+
lg: { dot: "h-3.5 w-3.5", iconDot: "h-10 w-10", padY: "py-5", densePadY: "py-3", title: "text-lg", desc: "text-sm", time: "text-xs", icon: "h-5 w-5" },
|
|
8531
|
+
xl: { dot: "h-4 w-4", iconDot: "h-12 w-12", padY: "py-6", densePadY: "py-3.5", title: "text-xl", desc: "text-base", time: "text-sm", icon: "h-6 w-6" }
|
|
8532
|
+
};
|
|
8533
|
+
var STATUS_COLOR = {
|
|
8534
|
+
default: "bg-muted/60",
|
|
8535
|
+
primary: "bg-primary",
|
|
8536
|
+
success: "bg-green-500",
|
|
8537
|
+
warning: "bg-yellow-500",
|
|
8538
|
+
error: "bg-red-500",
|
|
8539
|
+
info: "bg-blue-500"
|
|
8540
|
+
};
|
|
8541
|
+
var TimelineContext = React33.createContext(null);
|
|
8542
|
+
var LINE_STYLE_MAP = {
|
|
8543
|
+
solid: "border-solid",
|
|
8544
|
+
dashed: "border-dashed",
|
|
8545
|
+
dotted: "border-dotted"
|
|
8546
|
+
};
|
|
8547
|
+
var Marker = ({ index, last, size, color, status = "default", lineColor, lineStyle, active, dot, icon: Icon, showLine }) => {
|
|
8548
|
+
const sz = SIZE_STYLE[size];
|
|
8549
|
+
const dotColor = color ? `background:${color}` : void 0;
|
|
8550
|
+
const cls = color ? void 0 : STATUS_COLOR[status];
|
|
8551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
8552
|
+
dot ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex items-center justify-center", children: dot }) : Icon ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8553
|
+
"div",
|
|
8554
|
+
{
|
|
8555
|
+
className: cn("rounded-full ring-2 ring-background flex items-center justify-center", sz.iconDot, cls, active && "ring-primary/40 ring-4"),
|
|
8556
|
+
style: dotColor ? { background: color } : void 0,
|
|
8557
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Icon, { className: cn("text-white", sz.icon) })
|
|
8558
|
+
}
|
|
8559
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8560
|
+
"div",
|
|
8561
|
+
{
|
|
8562
|
+
className: cn("rounded-full ring-2 ring-background", sz.dot, cls, active && "ring-primary/40 ring-4 scale-125"),
|
|
8563
|
+
style: dotColor ? { background: color } : void 0
|
|
8564
|
+
}
|
|
8565
|
+
),
|
|
8566
|
+
!last && showLine && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8567
|
+
"div",
|
|
8568
|
+
{
|
|
8569
|
+
className: cn("flex-1 border-l-2", LINE_STYLE_MAP[lineStyle]),
|
|
8570
|
+
style: { borderColor: lineColor || "hsl(var(--border))" }
|
|
8571
|
+
}
|
|
8572
|
+
)
|
|
8573
|
+
] });
|
|
8574
|
+
};
|
|
8575
|
+
var TimelineRoot = React33.forwardRef(
|
|
8576
|
+
({
|
|
8577
|
+
align = "left",
|
|
8578
|
+
variant = "default",
|
|
8579
|
+
size = "md",
|
|
8580
|
+
mode = "vertical",
|
|
8581
|
+
lineColor,
|
|
8582
|
+
lineStyle = "solid",
|
|
8583
|
+
items,
|
|
8584
|
+
itemClassName,
|
|
8585
|
+
animate = false,
|
|
8586
|
+
dense = false,
|
|
8587
|
+
showLine = true,
|
|
8588
|
+
className,
|
|
8589
|
+
children,
|
|
8590
|
+
...rest
|
|
8591
|
+
}, ref) => {
|
|
8592
|
+
const content = items ? items.map((it, i) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(TimelineItem, { ...it, className: cn(itemClassName, it.className), "data-index": i, "data-last": i === (items?.length ?? 0) - 1 }, i)) : children;
|
|
8593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(TimelineContext.Provider, { value: { align, variant, size, mode, lineColor, lineStyle, itemClassName, animate, dense, showLine }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8594
|
+
"div",
|
|
8595
|
+
{
|
|
8596
|
+
ref,
|
|
8597
|
+
className: cn(
|
|
8598
|
+
"relative",
|
|
8599
|
+
mode === "horizontal" && "flex gap-4 overflow-x-auto",
|
|
8600
|
+
mode === "vertical" && "space-y-0",
|
|
8601
|
+
className
|
|
8602
|
+
),
|
|
8603
|
+
...rest,
|
|
8604
|
+
children: mode === "vertical" ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "space-y-0", children: content }) : content
|
|
8605
|
+
}
|
|
8606
|
+
) });
|
|
8607
|
+
}
|
|
8608
|
+
);
|
|
8609
|
+
TimelineRoot.displayName = "Timeline";
|
|
8610
|
+
var TimelineItem = React33.forwardRef(
|
|
8611
|
+
({
|
|
8612
|
+
title,
|
|
8613
|
+
description,
|
|
8614
|
+
time,
|
|
8615
|
+
icon: Icon,
|
|
8616
|
+
status = "default",
|
|
8617
|
+
color,
|
|
8618
|
+
active = false,
|
|
8619
|
+
dot,
|
|
8620
|
+
collapsible = false,
|
|
8621
|
+
expanded: controlledExpanded,
|
|
8622
|
+
onExpandChange,
|
|
8623
|
+
expandContent,
|
|
8624
|
+
badge,
|
|
8625
|
+
className,
|
|
8626
|
+
children,
|
|
8627
|
+
...rest
|
|
8628
|
+
}, ref) => {
|
|
8629
|
+
const ctx = React33.useContext(TimelineContext);
|
|
8630
|
+
const idx = rest["data-index"];
|
|
8631
|
+
const isLast = Boolean(rest["data-last"]);
|
|
8632
|
+
const sz = SIZE_STYLE[ctx.size];
|
|
8633
|
+
const [internalExpanded, setInternalExpanded] = React33.useState(false);
|
|
8634
|
+
const isExpanded = controlledExpanded !== void 0 ? controlledExpanded : internalExpanded;
|
|
8635
|
+
const toggleExpanded = () => {
|
|
8636
|
+
const newExpanded = !isExpanded;
|
|
8637
|
+
if (onExpandChange) {
|
|
8638
|
+
onExpandChange(newExpanded);
|
|
8639
|
+
} else {
|
|
8640
|
+
setInternalExpanded(newExpanded);
|
|
8641
|
+
}
|
|
8642
|
+
};
|
|
8643
|
+
const padding = ctx.dense ? sz.densePadY : sz.padY;
|
|
8644
|
+
const variantClasses = {
|
|
8645
|
+
default: "",
|
|
8646
|
+
outlined: "rounded-lg border border-border bg-card shadow-sm px-4 py-3",
|
|
8647
|
+
card: "rounded-xl border border-border bg-card shadow-md px-5 py-4",
|
|
8648
|
+
minimal: "border-l-2 pl-4 py-2",
|
|
8649
|
+
modern: "rounded-lg bg-gradient-to-r from-card to-muted/20 border border-border/50 px-5 py-4 backdrop-blur-sm",
|
|
8650
|
+
gradient: "rounded-xl bg-gradient-to-br from-primary/10 via-card to-accent/10 border border-primary/20 px-5 py-4 shadow-lg"
|
|
8651
|
+
};
|
|
8652
|
+
const contentBox = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("min-w-0 flex-1", variantClasses[ctx.variant]), children: [
|
|
8653
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
8654
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
8655
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8656
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("font-semibold text-foreground", sz.title), children: title }),
|
|
8657
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "px-2 py-0.5 rounded-full text-[10px] font-medium bg-primary/10 text-primary", children: badge })
|
|
8658
|
+
] }),
|
|
8659
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("text-muted-foreground mt-1", sz.desc), children: description }),
|
|
8660
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mt-2", children })
|
|
8661
|
+
] }),
|
|
8662
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8663
|
+
"button",
|
|
8664
|
+
{
|
|
8665
|
+
type: "button",
|
|
8666
|
+
onClick: toggleExpanded,
|
|
8667
|
+
className: cn("text-muted-foreground hover:text-foreground transition-transform p-1", isExpanded && "rotate-180"),
|
|
8668
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react23.ChevronDown, { className: "h-4 w-4" })
|
|
8669
|
+
}
|
|
8670
|
+
)
|
|
8671
|
+
] }),
|
|
8672
|
+
time && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("mt-2 text-muted-foreground flex items-center gap-1", sz.time), children: time }),
|
|
8673
|
+
collapsible && isExpanded && expandContent && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mt-3 pt-3 border-t border-border/50 text-sm", children: expandContent })
|
|
8674
|
+
] });
|
|
8675
|
+
const markerWidth = Icon || dot ? "w-auto" : "w-6";
|
|
8676
|
+
const leftSide = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex items-stretch gap-4", padding, ctx.animate && "animate-in slide-in-from-left duration-500"), style: { animationDelay: ctx.animate ? `${(idx ?? 0) * 100}ms` : void 0 }, children: [
|
|
8677
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("flex-shrink-0 flex items-stretch", markerWidth), children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Marker, { index: idx ?? 0, last: isLast, size: ctx.size, color, status, lineColor: ctx.lineColor, lineStyle: ctx.lineStyle, active, dot, icon: Icon, showLine: ctx.showLine }) }),
|
|
8678
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex-1", children: contentBox })
|
|
8679
|
+
] });
|
|
8680
|
+
const rightSide = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex items-stretch gap-4", padding, ctx.animate && "animate-in slide-in-from-right duration-500"), style: { animationDelay: ctx.animate ? `${(idx ?? 0) * 100}ms` : void 0 }, children: [
|
|
8681
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex-1 flex justify-end", children: contentBox }),
|
|
8682
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("flex-shrink-0 flex items-stretch", markerWidth), children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Marker, { index: idx ?? 0, last: isLast, size: ctx.size, color, status, lineColor: ctx.lineColor, lineStyle: ctx.lineStyle, active, dot, icon: Icon, showLine: ctx.showLine }) })
|
|
8683
|
+
] });
|
|
8684
|
+
const horizontalItem = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8685
|
+
"div",
|
|
8686
|
+
{
|
|
8687
|
+
className: cn(
|
|
8688
|
+
"flex flex-col items-center gap-2 min-w-[200px]",
|
|
8689
|
+
ctx.animate && "animate-in fade-in-50 zoom-in-95 duration-500"
|
|
8690
|
+
),
|
|
8691
|
+
style: { animationDelay: ctx.animate ? `${(idx ?? 0) * 100}ms` : void 0 },
|
|
8692
|
+
children: [
|
|
8693
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Marker, { index: idx ?? 0, last: isLast, size: ctx.size, color, status, lineColor: ctx.lineColor, lineStyle: ctx.lineStyle, active, dot, icon: Icon, showLine: false }),
|
|
8694
|
+
!isLast && ctx.showLine && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("h-px w-full border-t-2", LINE_STYLE_MAP[ctx.lineStyle]), style: { borderColor: ctx.lineColor || "hsl(var(--border))" } }),
|
|
8695
|
+
contentBox
|
|
8696
|
+
]
|
|
8697
|
+
}
|
|
8698
|
+
);
|
|
8699
|
+
if (ctx.mode === "horizontal") {
|
|
8700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ref, className: cn("relative", className), ...rest, children: horizontalItem });
|
|
8701
|
+
}
|
|
8702
|
+
let row = leftSide;
|
|
8703
|
+
if (ctx.align === "right") row = rightSide;
|
|
8704
|
+
if (ctx.align === "alternate") row = (idx ?? 0) % 2 === 0 ? leftSide : rightSide;
|
|
8705
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ref, className: cn("relative", className), ...rest, children: row });
|
|
8706
|
+
}
|
|
8707
|
+
);
|
|
8708
|
+
TimelineItem.displayName = "Timeline.Item";
|
|
8709
|
+
var Timeline = Object.assign(TimelineRoot, { Item: TimelineItem });
|
|
8710
|
+
var Timeline_default = Timeline;
|
|
8711
|
+
|
|
8712
|
+
// ../../components/ui/ColorPicker.tsx
|
|
8713
|
+
var React34 = __toESM(require("react"), 1);
|
|
8714
|
+
var import_lucide_react24 = require("lucide-react");
|
|
8715
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8716
|
+
var clamp = (n, min, max) => Math.max(min, Math.min(max, n));
|
|
8717
|
+
function hexToRgb(hex) {
|
|
8718
|
+
const str = hex.replace(/^#/, "").trim();
|
|
8719
|
+
if (str.length === 3) {
|
|
8720
|
+
const r = parseInt(str[0] + str[0], 16);
|
|
8721
|
+
const g = parseInt(str[1] + str[1], 16);
|
|
8722
|
+
const b = parseInt(str[2] + str[2], 16);
|
|
8723
|
+
return { r, g, b };
|
|
8724
|
+
}
|
|
8725
|
+
if (str.length === 6) {
|
|
8726
|
+
const r = parseInt(str.slice(0, 2), 16);
|
|
8727
|
+
const g = parseInt(str.slice(2, 4), 16);
|
|
8728
|
+
const b = parseInt(str.slice(4, 6), 16);
|
|
8729
|
+
return { r, g, b };
|
|
8730
|
+
}
|
|
8731
|
+
return null;
|
|
8732
|
+
}
|
|
8733
|
+
function rgbToHex(r, g, b) {
|
|
8734
|
+
return `#${[r, g, b].map((v) => clamp(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
|
|
8735
|
+
}
|
|
8736
|
+
function rgbToHsl(r, g, b) {
|
|
8737
|
+
r /= 255;
|
|
8738
|
+
g /= 255;
|
|
8739
|
+
b /= 255;
|
|
8740
|
+
const max = Math.max(r, g, b);
|
|
8741
|
+
const min = Math.min(r, g, b);
|
|
8742
|
+
let h = 0, s = 0;
|
|
8743
|
+
const l = (max + min) / 2;
|
|
8744
|
+
if (max !== min) {
|
|
8745
|
+
const d = max - min;
|
|
8746
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
8747
|
+
switch (max) {
|
|
8748
|
+
case r:
|
|
8749
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
8750
|
+
break;
|
|
8751
|
+
case g:
|
|
8752
|
+
h = ((b - r) / d + 2) / 6;
|
|
8753
|
+
break;
|
|
8754
|
+
case b:
|
|
8755
|
+
h = ((r - g) / d + 4) / 6;
|
|
8756
|
+
break;
|
|
8757
|
+
}
|
|
8758
|
+
}
|
|
8759
|
+
return { h: h * 360, s: s * 100, l: l * 100 };
|
|
8760
|
+
}
|
|
8761
|
+
function hslToRgb(h, s, l) {
|
|
8762
|
+
h /= 360;
|
|
8763
|
+
s /= 100;
|
|
8764
|
+
l /= 100;
|
|
8765
|
+
let r, g, b;
|
|
8766
|
+
if (s === 0) {
|
|
8767
|
+
r = g = b = l;
|
|
8768
|
+
} else {
|
|
8769
|
+
const hue2rgb = (p2, q2, t) => {
|
|
8770
|
+
if (t < 0) t += 1;
|
|
8771
|
+
if (t > 1) t -= 1;
|
|
8772
|
+
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
8773
|
+
if (t < 1 / 2) return q2;
|
|
8774
|
+
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
8775
|
+
return p2;
|
|
8776
|
+
};
|
|
8777
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
8778
|
+
const p = 2 * l - q;
|
|
8779
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
8780
|
+
g = hue2rgb(p, q, h);
|
|
8781
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
8782
|
+
}
|
|
8783
|
+
return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };
|
|
8784
|
+
}
|
|
8785
|
+
function parseAnyColor(input) {
|
|
8786
|
+
if (!input) return null;
|
|
8787
|
+
const s = input.trim();
|
|
8788
|
+
if (s.startsWith("#")) {
|
|
8789
|
+
const rgb = hexToRgb(s);
|
|
8790
|
+
if (!rgb) return null;
|
|
8791
|
+
return { ...rgb, a: 1 };
|
|
8792
|
+
}
|
|
8793
|
+
const rgbaMatch = s.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)/i);
|
|
8794
|
+
if (rgbaMatch) {
|
|
8795
|
+
const r = clamp(parseInt(rgbaMatch[1], 10), 0, 255);
|
|
8796
|
+
const g = clamp(parseInt(rgbaMatch[2], 10), 0, 255);
|
|
8797
|
+
const b = clamp(parseInt(rgbaMatch[3], 10), 0, 255);
|
|
8798
|
+
const a = rgbaMatch[4] != null ? clamp(parseFloat(rgbaMatch[4]), 0, 1) : 1;
|
|
8799
|
+
return { r, g, b, a };
|
|
8800
|
+
}
|
|
8801
|
+
const hslaMatch = s.match(/hsla?\(\s*(\d{1,3}(?:\.\d+)?)\s*,?\s*(\d{1,3}(?:\.\d+)?)%?\s*,?\s*(\d{1,3}(?:\.\d+)?)%?(?:\s*,?\s*(\d*\.?\d+))?\s*\)/i);
|
|
8802
|
+
if (hslaMatch) {
|
|
8803
|
+
const h = parseFloat(hslaMatch[1]);
|
|
8804
|
+
const sl = parseFloat(hslaMatch[2]);
|
|
8805
|
+
const l = parseFloat(hslaMatch[3]);
|
|
8806
|
+
const a = hslaMatch[4] != null ? clamp(parseFloat(hslaMatch[4]), 0, 1) : 1;
|
|
8807
|
+
const rgb = hslToRgb(h, sl, l);
|
|
8808
|
+
return { ...rgb, a };
|
|
8809
|
+
}
|
|
8810
|
+
return null;
|
|
8811
|
+
}
|
|
8812
|
+
function formatOutput({ r, g, b, a }, withAlpha, format) {
|
|
8813
|
+
if (format === "hex" && (!withAlpha || a === 1)) {
|
|
8814
|
+
return rgbToHex(r, g, b);
|
|
8815
|
+
}
|
|
8816
|
+
if (format === "hsl" || format === "hsla") {
|
|
8817
|
+
const hsl = rgbToHsl(r, g, b);
|
|
8818
|
+
if (format === "hsla" || withAlpha) {
|
|
8819
|
+
return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp(a, 0, 1)})`;
|
|
8820
|
+
}
|
|
8821
|
+
return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
|
|
8822
|
+
}
|
|
8823
|
+
if (withAlpha || a !== 1) {
|
|
8824
|
+
return `rgba(${clamp(r, 0, 255)}, ${clamp(g, 0, 255)}, ${clamp(b, 0, 255)}, ${clamp(a, 0, 1)})`;
|
|
8825
|
+
}
|
|
8826
|
+
return rgbToHex(r, g, b);
|
|
8827
|
+
}
|
|
8828
|
+
function getColorHarmony(rgba) {
|
|
8829
|
+
const hsl = rgbToHsl(rgba.r, rgba.g, rgba.b);
|
|
8830
|
+
const compH = (hsl.h + 180) % 360;
|
|
8831
|
+
const compRgb = hslToRgb(compH, hsl.s, hsl.l);
|
|
8832
|
+
const tri1H = (hsl.h + 120) % 360;
|
|
8833
|
+
const tri2H = (hsl.h + 240) % 360;
|
|
8834
|
+
const tri1Rgb = hslToRgb(tri1H, hsl.s, hsl.l);
|
|
8835
|
+
const tri2Rgb = hslToRgb(tri2H, hsl.s, hsl.l);
|
|
8836
|
+
const ana1H = (hsl.h + 30) % 360;
|
|
8837
|
+
const ana2H = (hsl.h - 30 + 360) % 360;
|
|
8838
|
+
const ana1Rgb = hslToRgb(ana1H, hsl.s, hsl.l);
|
|
8839
|
+
const ana2Rgb = hslToRgb(ana2H, hsl.s, hsl.l);
|
|
8840
|
+
return {
|
|
8841
|
+
complementary: rgbToHex(compRgb.r, compRgb.g, compRgb.b),
|
|
8842
|
+
triadic: [rgbToHex(tri1Rgb.r, tri1Rgb.g, tri1Rgb.b), rgbToHex(tri2Rgb.r, tri2Rgb.g, tri2Rgb.b)],
|
|
8843
|
+
analogous: [rgbToHex(ana1Rgb.r, ana1Rgb.g, ana1Rgb.b), rgbToHex(ana2Rgb.r, ana2Rgb.g, ana2Rgb.b)]
|
|
8844
|
+
};
|
|
8845
|
+
}
|
|
8846
|
+
var DEFAULT_PRESETS = [
|
|
8847
|
+
"#000000",
|
|
8848
|
+
"#ffffff",
|
|
8849
|
+
"#f87171",
|
|
8850
|
+
"#fb923c",
|
|
8851
|
+
"#fbbf24",
|
|
8852
|
+
"#34d399",
|
|
8853
|
+
"#60a5fa",
|
|
8854
|
+
"#a78bfa",
|
|
8855
|
+
"#f472b6",
|
|
8856
|
+
"#111827",
|
|
8857
|
+
"#4b5563",
|
|
8858
|
+
"#9ca3af",
|
|
8859
|
+
"#d1d5db",
|
|
8860
|
+
"#e5e7eb",
|
|
8861
|
+
"#f3f4f6"
|
|
8862
|
+
];
|
|
8863
|
+
var Swatch = ({
|
|
8864
|
+
color,
|
|
8865
|
+
onClick,
|
|
8866
|
+
ariaLabel,
|
|
8867
|
+
size = "md"
|
|
8868
|
+
}) => {
|
|
8869
|
+
const sizeClasses2 = {
|
|
8870
|
+
sm: "h-5 w-5",
|
|
8871
|
+
md: "h-6 w-6",
|
|
8872
|
+
lg: "h-8 w-8"
|
|
8873
|
+
};
|
|
8874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8875
|
+
"button",
|
|
8876
|
+
{
|
|
8877
|
+
type: "button",
|
|
8878
|
+
className: cn(
|
|
8879
|
+
sizeClasses2[size],
|
|
8880
|
+
"rounded-md border border-border shadow-sm hover:scale-110 transition-transform",
|
|
8881
|
+
onClick && "cursor-pointer"
|
|
8882
|
+
),
|
|
8883
|
+
style: { backgroundColor: color },
|
|
8884
|
+
onClick,
|
|
8885
|
+
"aria-label": ariaLabel
|
|
8886
|
+
}
|
|
8887
|
+
);
|
|
8888
|
+
};
|
|
8889
|
+
function ColorPicker({
|
|
8890
|
+
value,
|
|
8891
|
+
defaultValue = "#4f46e5",
|
|
8892
|
+
onChange,
|
|
8893
|
+
disabled = false,
|
|
8894
|
+
withAlpha = false,
|
|
8895
|
+
format = "hex",
|
|
8896
|
+
presets,
|
|
8897
|
+
className,
|
|
8898
|
+
triggerClassName,
|
|
8899
|
+
contentClassName,
|
|
8900
|
+
clearable = false,
|
|
8901
|
+
copyable = true,
|
|
8902
|
+
size = "md",
|
|
8903
|
+
variant = "default",
|
|
8904
|
+
showRecent = false,
|
|
8905
|
+
showHarmony = false,
|
|
8906
|
+
maxRecent = 8,
|
|
8907
|
+
...rest
|
|
8908
|
+
}) {
|
|
8909
|
+
const isControlled = value !== void 0;
|
|
8910
|
+
const initial = parseAnyColor(isControlled ? value : defaultValue) || { r: 79, g: 70, b: 229, a: 1 };
|
|
8911
|
+
const [rgba, setRgba] = React34.useState(initial);
|
|
8912
|
+
const [open, setOpen] = React34.useState(false);
|
|
8913
|
+
const [text, setText] = React34.useState(() => formatOutput(initial, withAlpha, format));
|
|
8914
|
+
const [copied, setCopied] = React34.useState(false);
|
|
8915
|
+
const [recentColors, setRecentColors] = React34.useState([]);
|
|
8916
|
+
React34.useEffect(() => {
|
|
8917
|
+
if (isControlled) {
|
|
8918
|
+
const parsed = parseAnyColor(value);
|
|
8919
|
+
if (parsed) {
|
|
8920
|
+
setRgba(parsed);
|
|
8921
|
+
setText(formatOutput(parsed, withAlpha, format));
|
|
8922
|
+
}
|
|
8923
|
+
}
|
|
8924
|
+
}, [value]);
|
|
8925
|
+
const emit = (next) => {
|
|
8926
|
+
const out = formatOutput(next, withAlpha, format);
|
|
8927
|
+
if (!isControlled) setText(out);
|
|
8928
|
+
onChange?.(out);
|
|
8929
|
+
if (showRecent) {
|
|
8930
|
+
const hexColor = rgbToHex(next.r, next.g, next.b);
|
|
8931
|
+
setRecentColors((prev) => {
|
|
8932
|
+
const filtered = prev.filter((c) => c !== hexColor);
|
|
8933
|
+
return [hexColor, ...filtered].slice(0, maxRecent);
|
|
8934
|
+
});
|
|
8935
|
+
}
|
|
8936
|
+
};
|
|
8937
|
+
const copyToClipboard = async () => {
|
|
8938
|
+
try {
|
|
8939
|
+
await navigator.clipboard.writeText(text);
|
|
8940
|
+
setCopied(true);
|
|
8941
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
8942
|
+
} catch (err) {
|
|
8943
|
+
console.error("Failed to copy:", err);
|
|
8944
|
+
}
|
|
8945
|
+
};
|
|
8946
|
+
const handleHexChange = (raw) => {
|
|
8947
|
+
setText(raw);
|
|
8948
|
+
const parsed = parseAnyColor(raw);
|
|
8949
|
+
if (parsed) {
|
|
8950
|
+
setRgba((prev) => ({ ...parsed, a: withAlpha ? parsed.a : 1 }));
|
|
8951
|
+
emit({ ...parsed, a: withAlpha ? parsed.a : 1 });
|
|
8952
|
+
}
|
|
8953
|
+
};
|
|
8954
|
+
const handleNativeChange = (e) => {
|
|
8955
|
+
const hex = e.target.value || "#000000";
|
|
8956
|
+
const rgb = hexToRgb(hex) || { r: 0, g: 0, b: 0 };
|
|
8957
|
+
const next = { ...rgba, ...rgb };
|
|
8958
|
+
setRgba(next);
|
|
8959
|
+
emit(next);
|
|
8960
|
+
};
|
|
8961
|
+
const setAlpha = (aPct) => {
|
|
8962
|
+
const a = clamp(aPct / 100, 0, 1);
|
|
8963
|
+
const next = { ...rgba, a };
|
|
8964
|
+
setRgba(next);
|
|
8965
|
+
emit(next);
|
|
8966
|
+
};
|
|
8967
|
+
const tryEyedropper = async () => {
|
|
8968
|
+
if (typeof window !== "undefined" && window.EyeDropper) {
|
|
8969
|
+
const eye = new window.EyeDropper();
|
|
8970
|
+
try {
|
|
8971
|
+
const res = await eye.open();
|
|
8972
|
+
const rgb = hexToRgb(res.sRGBHex);
|
|
8973
|
+
if (rgb) {
|
|
8974
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
8975
|
+
setRgba(next);
|
|
8976
|
+
emit(next);
|
|
8977
|
+
}
|
|
8978
|
+
} catch {
|
|
8979
|
+
}
|
|
8980
|
+
}
|
|
8981
|
+
};
|
|
8982
|
+
const clear = () => {
|
|
8983
|
+
setText("");
|
|
8984
|
+
const next = { r: 0, g: 0, b: 0, a: 0 };
|
|
8985
|
+
setRgba(next);
|
|
8986
|
+
onChange?.("");
|
|
8987
|
+
};
|
|
8988
|
+
const swatches = presets && presets.length ? presets : DEFAULT_PRESETS;
|
|
8989
|
+
const hexForInput = rgbToHex(rgba.r, rgba.g, rgba.b);
|
|
8990
|
+
const alphaPct = Math.round(rgba.a * 100);
|
|
8991
|
+
const harmony = showHarmony ? getColorHarmony(rgba) : null;
|
|
8992
|
+
const sizeClasses2 = {
|
|
8993
|
+
sm: "h-8 text-xs",
|
|
8994
|
+
md: "h-10 text-sm",
|
|
8995
|
+
lg: "h-12 text-base"
|
|
8996
|
+
};
|
|
8997
|
+
const swatchSize = size === "sm" ? "sm" : size === "lg" ? "lg" : "md";
|
|
8998
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
8999
|
+
"button",
|
|
9000
|
+
{
|
|
9001
|
+
type: "button",
|
|
9002
|
+
disabled,
|
|
9003
|
+
className: cn(
|
|
9004
|
+
"w-full px-3 rounded-lg border border-input bg-background flex items-center justify-between",
|
|
9005
|
+
sizeClasses2[size],
|
|
9006
|
+
"hover:border-accent-foreground/30 transition-colors",
|
|
9007
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
9008
|
+
triggerClassName
|
|
9009
|
+
),
|
|
9010
|
+
"aria-label": "Open color picker",
|
|
9011
|
+
children: [
|
|
9012
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9013
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9014
|
+
"span",
|
|
9015
|
+
{
|
|
9016
|
+
className: cn(
|
|
9017
|
+
"rounded border border-border shadow-sm",
|
|
9018
|
+
size === "sm" ? "h-4 w-4" : size === "lg" ? "h-6 w-6" : "h-5 w-5"
|
|
9019
|
+
),
|
|
9020
|
+
style: { backgroundColor: withAlpha ? `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})` : hexForInput }
|
|
9021
|
+
}
|
|
9022
|
+
),
|
|
9023
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-mono text-muted-foreground", children: text })
|
|
9024
|
+
] }),
|
|
9025
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Pipette, { className: cn(size === "sm" ? "w-3.5 h-3.5" : size === "lg" ? "w-5 h-5" : "w-4 h-4", "text-muted-foreground") })
|
|
9026
|
+
]
|
|
9027
|
+
}
|
|
9028
|
+
);
|
|
9029
|
+
const contentWidthByVariant = {
|
|
9030
|
+
minimal: 240,
|
|
9031
|
+
compact: 280,
|
|
9032
|
+
default: 320,
|
|
9033
|
+
full: 360
|
|
9034
|
+
};
|
|
9035
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: cn("inline-block w-full", className), ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9036
|
+
Popover,
|
|
9037
|
+
{
|
|
9038
|
+
trigger,
|
|
9039
|
+
open,
|
|
9040
|
+
onOpenChange: setOpen,
|
|
9041
|
+
placement: "bottom-start",
|
|
9042
|
+
matchTriggerWidth: variant === "minimal",
|
|
9043
|
+
contentWidth: contentWidthByVariant[variant],
|
|
9044
|
+
contentClassName: cn("p-3 rounded-lg border border-border bg-card shadow-lg", contentClassName),
|
|
9045
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-3", children: [
|
|
9046
|
+
variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9047
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("input", { type: "color", value: hexForInput, onChange: handleNativeChange, className: "h-9 w-9 rounded-md cursor-pointer border border-border" }),
|
|
9048
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
9049
|
+
"button",
|
|
9050
|
+
{
|
|
9051
|
+
type: "button",
|
|
9052
|
+
onClick: tryEyedropper,
|
|
9053
|
+
className: cn("h-9 px-3 rounded-md border border-border text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5"),
|
|
9054
|
+
children: [
|
|
9055
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Pipette, { className: "w-3.5 h-3.5" }),
|
|
9056
|
+
variant === "full" && "Pick"
|
|
9057
|
+
]
|
|
9058
|
+
}
|
|
9059
|
+
),
|
|
9060
|
+
copyable && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
9061
|
+
"button",
|
|
9062
|
+
{
|
|
9063
|
+
type: "button",
|
|
9064
|
+
onClick: copyToClipboard,
|
|
9065
|
+
className: cn(
|
|
9066
|
+
"h-9 px-3 rounded-md border border-border text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5",
|
|
9067
|
+
copied && "bg-green-500/10 border-green-500/30"
|
|
9068
|
+
),
|
|
9069
|
+
children: [
|
|
9070
|
+
copied ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Check, { className: "w-3.5 h-3.5 text-green-600" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Copy, { className: "w-3.5 h-3.5" }),
|
|
9071
|
+
variant === "full" && (copied ? "Copied!" : "Copy")
|
|
9072
|
+
]
|
|
9073
|
+
}
|
|
9074
|
+
),
|
|
9075
|
+
clearable && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
9076
|
+
"button",
|
|
9077
|
+
{
|
|
9078
|
+
type: "button",
|
|
9079
|
+
onClick: clear,
|
|
9080
|
+
className: "ml-auto h-9 px-2 rounded-md border border-border text-xs hover:bg-destructive/10 transition-colors flex items-center gap-1",
|
|
9081
|
+
children: [
|
|
9082
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.X, { className: "w-3.5 h-3.5" }),
|
|
9083
|
+
variant === "full" && "Clear"
|
|
9084
|
+
]
|
|
9085
|
+
}
|
|
9086
|
+
)
|
|
9087
|
+
] }),
|
|
9088
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9089
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9090
|
+
Input_default,
|
|
9091
|
+
{
|
|
9092
|
+
value: text,
|
|
9093
|
+
onChange: (e) => handleHexChange(e.target.value),
|
|
9094
|
+
placeholder: format === "hsl" || format === "hsla" ? "hsl(240, 82%, 59%)" : withAlpha || format === "rgba" ? "rgba(79,70,229,1)" : "#4f46e5",
|
|
9095
|
+
variant: "outlined",
|
|
9096
|
+
size: "sm",
|
|
9097
|
+
className: "flex-1"
|
|
9098
|
+
}
|
|
9099
|
+
),
|
|
9100
|
+
variant === "minimal" && copyable && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9101
|
+
"button",
|
|
9102
|
+
{
|
|
9103
|
+
type: "button",
|
|
9104
|
+
onClick: copyToClipboard,
|
|
9105
|
+
className: cn(
|
|
9106
|
+
"h-9 w-9 rounded-md border border-border hover:bg-accent/10 transition-colors flex items-center justify-center",
|
|
9107
|
+
copied && "bg-green-500/10 border-green-500/30"
|
|
9108
|
+
),
|
|
9109
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Check, { className: "w-3.5 h-3.5 text-green-600" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Copy, { className: "w-3.5 h-3.5" })
|
|
9110
|
+
}
|
|
9111
|
+
)
|
|
9112
|
+
] }),
|
|
9113
|
+
withAlpha && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Slider, { min: 0, max: 100, step: 1, value: alphaPct, onChange: (v) => setAlpha(v), label: "Alpha", showValue: true, formatValue: (v) => `${v}%`, size: "sm" }) }),
|
|
9114
|
+
variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
9115
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1.5", children: [
|
|
9116
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.Palette, { className: "w-3.5 h-3.5" }),
|
|
9117
|
+
" Presets"
|
|
9118
|
+
] }),
|
|
9119
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grid grid-cols-8 gap-2", children: swatches.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9120
|
+
Swatch,
|
|
9121
|
+
{
|
|
9122
|
+
color: c,
|
|
9123
|
+
ariaLabel: c,
|
|
9124
|
+
size: swatchSize,
|
|
9125
|
+
onClick: () => {
|
|
9126
|
+
const rgb = hexToRgb(c);
|
|
9127
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9128
|
+
setRgba(next);
|
|
9129
|
+
emit(next);
|
|
9130
|
+
}
|
|
9131
|
+
},
|
|
9132
|
+
c
|
|
9133
|
+
)) })
|
|
9134
|
+
] }),
|
|
9135
|
+
showRecent && recentColors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
9136
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1.5", children: [
|
|
9137
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react24.History, { className: "w-3.5 h-3.5" }),
|
|
9138
|
+
" Recent"
|
|
9139
|
+
] }),
|
|
9140
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex gap-2 flex-wrap", children: recentColors.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9141
|
+
Swatch,
|
|
9142
|
+
{
|
|
9143
|
+
color: c,
|
|
9144
|
+
ariaLabel: c,
|
|
9145
|
+
size: swatchSize,
|
|
9146
|
+
onClick: () => {
|
|
9147
|
+
const rgb = hexToRgb(c);
|
|
9148
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9149
|
+
setRgba(next);
|
|
9150
|
+
emit(next);
|
|
9151
|
+
}
|
|
9152
|
+
},
|
|
9153
|
+
`${c}-${i}`
|
|
9154
|
+
)) })
|
|
9155
|
+
] }),
|
|
9156
|
+
showHarmony && harmony && variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
9157
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Harmony" }),
|
|
9158
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-2", children: [
|
|
9159
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9160
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-xs text-muted-foreground w-24", children: "Complementary" }),
|
|
9161
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9162
|
+
Swatch,
|
|
9163
|
+
{
|
|
9164
|
+
color: harmony.complementary,
|
|
9165
|
+
ariaLabel: "Complementary",
|
|
9166
|
+
size: swatchSize,
|
|
9167
|
+
onClick: () => {
|
|
9168
|
+
const rgb = hexToRgb(harmony.complementary);
|
|
9169
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9170
|
+
setRgba(next);
|
|
9171
|
+
emit(next);
|
|
9172
|
+
}
|
|
9173
|
+
}
|
|
9174
|
+
),
|
|
9175
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-xs font-mono text-muted-foreground", children: harmony.complementary })
|
|
9176
|
+
] }),
|
|
9177
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9178
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-xs text-muted-foreground w-24", children: "Triadic" }),
|
|
9179
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex gap-2", children: harmony.triadic.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9180
|
+
Swatch,
|
|
9181
|
+
{
|
|
9182
|
+
color: c,
|
|
9183
|
+
ariaLabel: c,
|
|
9184
|
+
size: swatchSize,
|
|
9185
|
+
onClick: () => {
|
|
9186
|
+
const rgb = hexToRgb(c);
|
|
9187
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9188
|
+
setRgba(next);
|
|
9189
|
+
emit(next);
|
|
9190
|
+
}
|
|
9191
|
+
},
|
|
9192
|
+
c
|
|
9193
|
+
)) })
|
|
9194
|
+
] }),
|
|
9195
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9196
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-xs text-muted-foreground w-24", children: "Analogous" }),
|
|
9197
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex gap-2", children: harmony.analogous.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
9198
|
+
Swatch,
|
|
9199
|
+
{
|
|
9200
|
+
color: c,
|
|
9201
|
+
ariaLabel: c,
|
|
9202
|
+
size: swatchSize,
|
|
9203
|
+
onClick: () => {
|
|
9204
|
+
const rgb = hexToRgb(c);
|
|
9205
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9206
|
+
setRgba(next);
|
|
9207
|
+
emit(next);
|
|
9208
|
+
}
|
|
9209
|
+
},
|
|
9210
|
+
c
|
|
9211
|
+
)) })
|
|
9212
|
+
] })
|
|
9213
|
+
] })
|
|
9214
|
+
] })
|
|
9215
|
+
] })
|
|
9216
|
+
}
|
|
9217
|
+
) });
|
|
9218
|
+
}
|
|
9219
|
+
|
|
9220
|
+
// ../../components/ui/Grid.tsx
|
|
9221
|
+
var import_react20 = __toESM(require("react"), 1);
|
|
9222
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
9223
|
+
var BP_MIN = {
|
|
9224
|
+
sm: 640,
|
|
9225
|
+
md: 768,
|
|
9226
|
+
lg: 1024,
|
|
9227
|
+
xl: 1280,
|
|
9228
|
+
"2xl": 1536
|
|
9229
|
+
};
|
|
9230
|
+
function toTemplateCols(columns, minColumnWidth) {
|
|
9231
|
+
if (minColumnWidth != null) {
|
|
9232
|
+
const v = typeof minColumnWidth === "number" ? `${minColumnWidth}px` : String(minColumnWidth);
|
|
9233
|
+
return `repeat(auto-fit, minmax(${v}, 1fr))`;
|
|
9234
|
+
}
|
|
9235
|
+
if (typeof columns === "number") return `repeat(${columns}, minmax(0, 1fr))`;
|
|
9236
|
+
if (columns) return String(columns);
|
|
9237
|
+
return `repeat(12, minmax(0, 1fr))`;
|
|
9238
|
+
}
|
|
9239
|
+
function toTemplateRows(rows) {
|
|
9240
|
+
if (typeof rows === "number") return `repeat(${rows}, minmax(0, auto))`;
|
|
9241
|
+
if (rows) return String(rows);
|
|
9242
|
+
return void 0;
|
|
9243
|
+
}
|
|
9244
|
+
function joinAreas(areas) {
|
|
9245
|
+
if (!areas) return void 0;
|
|
9246
|
+
return Array.isArray(areas) ? areas.join(" ") : areas;
|
|
9247
|
+
}
|
|
9248
|
+
function getVariantClasses(variant = "default", outlined) {
|
|
9249
|
+
if (outlined) {
|
|
9250
|
+
return "rounded-lg md:rounded-xl bg-card text-card-foreground border border-border shadow-sm";
|
|
9251
|
+
}
|
|
9252
|
+
const variants = {
|
|
9253
|
+
default: "",
|
|
9254
|
+
bordered: "border border-border rounded-lg",
|
|
9255
|
+
card: "rounded-lg md:rounded-xl bg-card text-card-foreground border border-border shadow-sm",
|
|
9256
|
+
flat: "bg-muted/30 rounded-lg",
|
|
9257
|
+
glass: "bg-background/80 backdrop-blur-sm border border-border/50 rounded-lg shadow-lg"
|
|
9258
|
+
};
|
|
9259
|
+
return variants[variant] || "";
|
|
9260
|
+
}
|
|
9261
|
+
var GridRoot = import_react20.default.forwardRef(
|
|
9262
|
+
({
|
|
9263
|
+
columns,
|
|
9264
|
+
rows,
|
|
9265
|
+
gap,
|
|
9266
|
+
gapX,
|
|
9267
|
+
gapY,
|
|
9268
|
+
autoRows,
|
|
9269
|
+
autoColumns,
|
|
9270
|
+
autoFlow,
|
|
9271
|
+
minColumnWidth,
|
|
9272
|
+
areas,
|
|
9273
|
+
alignItems,
|
|
9274
|
+
justifyItems,
|
|
9275
|
+
alignContent,
|
|
9276
|
+
justifyContent,
|
|
9277
|
+
responsive,
|
|
9278
|
+
variant = "default",
|
|
9279
|
+
animated = false,
|
|
9280
|
+
outlined = false,
|
|
9281
|
+
className,
|
|
9282
|
+
style,
|
|
9283
|
+
children,
|
|
9284
|
+
...rest
|
|
9285
|
+
}, ref) => {
|
|
9286
|
+
const id = (0, import_react20.useId)().replace(/[:]/g, "");
|
|
9287
|
+
const baseClass = `uv-grid-${id}`;
|
|
9288
|
+
const baseCols = toTemplateCols(columns, minColumnWidth);
|
|
9289
|
+
const baseRows = toTemplateRows(rows);
|
|
9290
|
+
const baseAreas = joinAreas(areas);
|
|
9291
|
+
let css = `.${baseClass}{display:grid;`;
|
|
9292
|
+
if (baseCols) css += `grid-template-columns:${baseCols};`;
|
|
9293
|
+
if (baseRows) css += `grid-template-rows:${baseRows};`;
|
|
9294
|
+
if (baseAreas) css += `grid-template-areas:${baseAreas};`;
|
|
9295
|
+
if (autoRows) css += `grid-auto-rows:${autoRows};`;
|
|
9296
|
+
if (autoColumns) css += `grid-auto-columns:${autoColumns};`;
|
|
9297
|
+
if (autoFlow) css += `grid-auto-flow:${autoFlow};`;
|
|
9298
|
+
if (alignItems) css += `align-items:${alignItems};`;
|
|
9299
|
+
if (justifyItems) css += `justify-items:${justifyItems};`;
|
|
9300
|
+
if (alignContent) css += `align-content:${alignContent};`;
|
|
9301
|
+
if (justifyContent) css += `justify-content:${justifyContent};`;
|
|
9302
|
+
if (animated) css += `transition:all 0.3s cubic-bezier(0.4, 0, 0.2, 1);`;
|
|
9303
|
+
css += `}`;
|
|
9304
|
+
const toVal = (v) => typeof v === "number" ? `${v}px` : v;
|
|
9305
|
+
const g = toVal(gap);
|
|
9306
|
+
const gx = toVal(gapX);
|
|
9307
|
+
const gy = toVal(gapY);
|
|
9308
|
+
if (g) css += `.${baseClass}{gap:${g};}`;
|
|
9309
|
+
if (gx) css += `.${baseClass}{column-gap:${gx};}`;
|
|
9310
|
+
if (gy) css += `.${baseClass}{row-gap:${gy};}`;
|
|
9311
|
+
if (responsive) {
|
|
9312
|
+
Object.keys(responsive).forEach((bp) => {
|
|
9313
|
+
const conf = responsive[bp];
|
|
9314
|
+
if (!conf) return;
|
|
9315
|
+
const cols = toTemplateCols(conf.columns, conf.minColumnWidth);
|
|
9316
|
+
const rws = toTemplateRows(conf.rows);
|
|
9317
|
+
const rg = toVal(conf.gap);
|
|
9318
|
+
const rgx = toVal(conf.gapX);
|
|
9319
|
+
const rgy = toVal(conf.gapY);
|
|
9320
|
+
css += `@media (min-width:${BP_MIN[bp]}px){.${baseClass}{`;
|
|
9321
|
+
if (cols) css += `grid-template-columns:${cols};`;
|
|
9322
|
+
if (rws) css += `grid-template-rows:${rws};`;
|
|
9323
|
+
if (rg) css += `gap:${rg};`;
|
|
9324
|
+
if (rgx) css += `column-gap:${rgx};`;
|
|
9325
|
+
if (rgy) css += `row-gap:${rgy};`;
|
|
9326
|
+
css += `}}`;
|
|
9327
|
+
});
|
|
9328
|
+
}
|
|
9329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
9330
|
+
"div",
|
|
9331
|
+
{
|
|
9332
|
+
ref,
|
|
9333
|
+
className: cn(
|
|
9334
|
+
baseClass,
|
|
9335
|
+
getVariantClasses(variant, outlined),
|
|
9336
|
+
animated && "transition-all duration-300 ease-in-out",
|
|
9337
|
+
className
|
|
9338
|
+
),
|
|
9339
|
+
style,
|
|
9340
|
+
...rest,
|
|
9341
|
+
children: [
|
|
9342
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("style", { dangerouslySetInnerHTML: { __html: css } }),
|
|
9343
|
+
children
|
|
9344
|
+
]
|
|
9345
|
+
}
|
|
9346
|
+
);
|
|
9347
|
+
}
|
|
9348
|
+
);
|
|
9349
|
+
GridRoot.displayName = "Grid";
|
|
9350
|
+
var GridItem = import_react20.default.forwardRef(
|
|
9351
|
+
({
|
|
9352
|
+
colSpan,
|
|
9353
|
+
rowSpan,
|
|
9354
|
+
colStart,
|
|
9355
|
+
colEnd,
|
|
9356
|
+
rowStart,
|
|
9357
|
+
rowEnd,
|
|
9358
|
+
area,
|
|
9359
|
+
alignSelf,
|
|
9360
|
+
justifySelf,
|
|
9361
|
+
order,
|
|
9362
|
+
hoverable = false,
|
|
9363
|
+
animationDelay,
|
|
9364
|
+
style,
|
|
9365
|
+
className,
|
|
9366
|
+
...rest
|
|
9367
|
+
}, ref) => {
|
|
9368
|
+
const st = { ...style };
|
|
9369
|
+
if (colSpan != null) st.gridColumn = `span ${colSpan} / span ${colSpan}`;
|
|
9370
|
+
if (rowSpan != null) st.gridRow = `span ${rowSpan} / span ${rowSpan}`;
|
|
9371
|
+
if (colStart != null) st.gridColumnStart = colStart;
|
|
9372
|
+
if (colEnd != null) st.gridColumnEnd = colEnd;
|
|
9373
|
+
if (rowStart != null) st.gridRowStart = rowStart;
|
|
9374
|
+
if (rowEnd != null) st.gridRowEnd = rowEnd;
|
|
9375
|
+
if (area) st.gridArea = area;
|
|
9376
|
+
if (alignSelf) st.alignSelf = alignSelf;
|
|
9377
|
+
if (justifySelf) st.justifySelf = justifySelf;
|
|
9378
|
+
if (order != null) st.order = order;
|
|
9379
|
+
if (animationDelay != null) {
|
|
9380
|
+
st.animationDelay = `${animationDelay}ms`;
|
|
9381
|
+
st.opacity = 0;
|
|
9382
|
+
st.animation = `uvGridItemFadeIn 0.5s ease-out forwards`;
|
|
9383
|
+
}
|
|
9384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
9385
|
+
animationDelay != null && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
9386
|
+
"style",
|
|
9387
|
+
{
|
|
9388
|
+
dangerouslySetInnerHTML: {
|
|
9389
|
+
__html: `@keyframes uvGridItemFadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}`
|
|
9390
|
+
}
|
|
9391
|
+
}
|
|
9392
|
+
),
|
|
9393
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
9394
|
+
"div",
|
|
9395
|
+
{
|
|
9396
|
+
ref,
|
|
9397
|
+
className: cn(
|
|
9398
|
+
hoverable && "transition-all duration-200 hover:scale-[1.02] hover:shadow-md cursor-pointer",
|
|
9399
|
+
className
|
|
9400
|
+
),
|
|
9401
|
+
style: st,
|
|
9402
|
+
...rest
|
|
9403
|
+
}
|
|
9404
|
+
)
|
|
9405
|
+
] });
|
|
9406
|
+
}
|
|
9407
|
+
);
|
|
9408
|
+
GridItem.displayName = "Grid.Item";
|
|
9409
|
+
var Grid = Object.assign(GridRoot, { Item: GridItem });
|
|
9410
|
+
var Grid_default = Grid;
|
|
9411
|
+
|
|
7487
9412
|
// ../../components/ui/ClientOnly.tsx
|
|
7488
|
-
var
|
|
7489
|
-
var
|
|
9413
|
+
var import_react21 = require("react");
|
|
9414
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
7490
9415
|
function ClientOnly({ children, fallback = null }) {
|
|
7491
|
-
const [hasMounted, setHasMounted] = (0,
|
|
7492
|
-
(0,
|
|
9416
|
+
const [hasMounted, setHasMounted] = (0, import_react21.useState)(false);
|
|
9417
|
+
(0, import_react21.useEffect)(() => {
|
|
7493
9418
|
setHasMounted(true);
|
|
7494
9419
|
}, []);
|
|
7495
9420
|
if (!hasMounted) {
|
|
7496
|
-
return /* @__PURE__ */ (0,
|
|
9421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_jsx_runtime44.Fragment, { children: fallback });
|
|
7497
9422
|
}
|
|
7498
|
-
return /* @__PURE__ */ (0,
|
|
9423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_jsx_runtime44.Fragment, { children });
|
|
7499
9424
|
}
|
|
7500
9425
|
|
|
7501
9426
|
// ../../components/ui/Loading.tsx
|
|
7502
|
-
var
|
|
7503
|
-
var
|
|
9427
|
+
var import_lucide_react25 = require("lucide-react");
|
|
9428
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
7504
9429
|
var LoadingSpinner = ({
|
|
7505
9430
|
size = "md",
|
|
7506
9431
|
className,
|
|
@@ -7516,8 +9441,8 @@ var LoadingSpinner = ({
|
|
|
7516
9441
|
foreground: "text-foreground",
|
|
7517
9442
|
muted: "text-muted-foreground"
|
|
7518
9443
|
};
|
|
7519
|
-
return /* @__PURE__ */ (0,
|
|
7520
|
-
|
|
9444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
9445
|
+
import_lucide_react25.Activity,
|
|
7521
9446
|
{
|
|
7522
9447
|
className: cn(
|
|
7523
9448
|
"animate-spin",
|
|
@@ -7537,7 +9462,7 @@ var LoadingDots = ({
|
|
|
7537
9462
|
foreground: "bg-foreground",
|
|
7538
9463
|
muted: "bg-muted-foreground"
|
|
7539
9464
|
};
|
|
7540
|
-
return /* @__PURE__ */ (0,
|
|
9465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn("flex items-center space-x-1", className), children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
7541
9466
|
"div",
|
|
7542
9467
|
{
|
|
7543
9468
|
className: cn(
|
|
@@ -7559,7 +9484,7 @@ var LoadingBar = ({
|
|
|
7559
9484
|
label
|
|
7560
9485
|
}) => {
|
|
7561
9486
|
const pct = progress ? Math.min(Math.max(progress, 0), 100) : void 0;
|
|
7562
|
-
return /* @__PURE__ */ (0,
|
|
9487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
7563
9488
|
"div",
|
|
7564
9489
|
{
|
|
7565
9490
|
className: cn("w-full bg-muted rounded-full h-2", className),
|
|
@@ -7568,7 +9493,7 @@ var LoadingBar = ({
|
|
|
7568
9493
|
"aria-valuemax": pct === void 0 ? void 0 : 100,
|
|
7569
9494
|
"aria-valuenow": pct === void 0 ? void 0 : Math.round(pct),
|
|
7570
9495
|
"aria-label": label || "Loading",
|
|
7571
|
-
children: /* @__PURE__ */ (0,
|
|
9496
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
7572
9497
|
"div",
|
|
7573
9498
|
{
|
|
7574
9499
|
className: cn(
|
|
@@ -7585,10 +9510,10 @@ var LoadingBar = ({
|
|
|
7585
9510
|
};
|
|
7586
9511
|
|
|
7587
9512
|
// ../../components/ui/Table.tsx
|
|
7588
|
-
var
|
|
7589
|
-
var
|
|
7590
|
-
var Table =
|
|
7591
|
-
({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0,
|
|
9513
|
+
var import_react22 = __toESM(require("react"), 1);
|
|
9514
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
9515
|
+
var Table = import_react22.default.forwardRef(
|
|
9516
|
+
({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7592
9517
|
"div",
|
|
7593
9518
|
{
|
|
7594
9519
|
className: cn(
|
|
@@ -7598,7 +9523,7 @@ var Table = import_react21.default.forwardRef(
|
|
|
7598
9523
|
"backdrop-blur-sm transition-all duration-300",
|
|
7599
9524
|
containerClassName
|
|
7600
9525
|
),
|
|
7601
|
-
children: /* @__PURE__ */ (0,
|
|
9526
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7602
9527
|
"table",
|
|
7603
9528
|
{
|
|
7604
9529
|
ref,
|
|
@@ -7610,8 +9535,8 @@ var Table = import_react21.default.forwardRef(
|
|
|
7610
9535
|
)
|
|
7611
9536
|
);
|
|
7612
9537
|
Table.displayName = "Table";
|
|
7613
|
-
var TableHeader =
|
|
7614
|
-
({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ (0,
|
|
9538
|
+
var TableHeader = import_react22.default.forwardRef(
|
|
9539
|
+
({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
7615
9540
|
"thead",
|
|
7616
9541
|
{
|
|
7617
9542
|
ref,
|
|
@@ -7629,7 +9554,7 @@ var TableHeader = import_react21.default.forwardRef(
|
|
|
7629
9554
|
)
|
|
7630
9555
|
);
|
|
7631
9556
|
TableHeader.displayName = "TableHeader";
|
|
7632
|
-
var TableBody =
|
|
9557
|
+
var TableBody = import_react22.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7633
9558
|
"tbody",
|
|
7634
9559
|
{
|
|
7635
9560
|
ref,
|
|
@@ -7638,7 +9563,7 @@ var TableBody = import_react21.default.forwardRef(({ className, ...props }, ref)
|
|
|
7638
9563
|
}
|
|
7639
9564
|
));
|
|
7640
9565
|
TableBody.displayName = "TableBody";
|
|
7641
|
-
var TableFooter =
|
|
9566
|
+
var TableFooter = import_react22.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7642
9567
|
"tfoot",
|
|
7643
9568
|
{
|
|
7644
9569
|
ref,
|
|
@@ -7650,7 +9575,7 @@ var TableFooter = import_react21.default.forwardRef(({ className, ...props }, re
|
|
|
7650
9575
|
}
|
|
7651
9576
|
));
|
|
7652
9577
|
TableFooter.displayName = "TableFooter";
|
|
7653
|
-
var TableRow =
|
|
9578
|
+
var TableRow = import_react22.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7654
9579
|
"tr",
|
|
7655
9580
|
{
|
|
7656
9581
|
ref,
|
|
@@ -7664,7 +9589,7 @@ var TableRow = import_react21.default.forwardRef(({ className, ...props }, ref)
|
|
|
7664
9589
|
}
|
|
7665
9590
|
));
|
|
7666
9591
|
TableRow.displayName = "TableRow";
|
|
7667
|
-
var TableHead =
|
|
9592
|
+
var TableHead = import_react22.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7668
9593
|
"th",
|
|
7669
9594
|
{
|
|
7670
9595
|
ref,
|
|
@@ -7676,7 +9601,7 @@ var TableHead = import_react21.default.forwardRef(({ className, ...props }, ref)
|
|
|
7676
9601
|
}
|
|
7677
9602
|
));
|
|
7678
9603
|
TableHead.displayName = "TableHead";
|
|
7679
|
-
var TableCell =
|
|
9604
|
+
var TableCell = import_react22.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7680
9605
|
"td",
|
|
7681
9606
|
{
|
|
7682
9607
|
ref,
|
|
@@ -7685,7 +9610,7 @@ var TableCell = import_react21.default.forwardRef(({ className, ...props }, ref)
|
|
|
7685
9610
|
}
|
|
7686
9611
|
));
|
|
7687
9612
|
TableCell.displayName = "TableCell";
|
|
7688
|
-
var TableCaption =
|
|
9613
|
+
var TableCaption = import_react22.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
7689
9614
|
"caption",
|
|
7690
9615
|
{
|
|
7691
9616
|
ref,
|
|
@@ -7696,13 +9621,13 @@ var TableCaption = import_react21.default.forwardRef(({ className, ...props }, r
|
|
|
7696
9621
|
TableCaption.displayName = "TableCaption";
|
|
7697
9622
|
|
|
7698
9623
|
// ../../components/ui/DataTable.tsx
|
|
7699
|
-
var
|
|
7700
|
-
var
|
|
9624
|
+
var import_lucide_react26 = require("lucide-react");
|
|
9625
|
+
var import_react23 = __toESM(require("react"), 1);
|
|
7701
9626
|
var import_next_intl7 = require("next-intl");
|
|
7702
|
-
var
|
|
9627
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
7703
9628
|
function useDebounced(value, delay = 300) {
|
|
7704
|
-
const [debounced, setDebounced] =
|
|
7705
|
-
|
|
9629
|
+
const [debounced, setDebounced] = import_react23.default.useState(value);
|
|
9630
|
+
import_react23.default.useEffect(() => {
|
|
7706
9631
|
const id = setTimeout(() => setDebounced(value), delay);
|
|
7707
9632
|
return () => clearTimeout(id);
|
|
7708
9633
|
}, [value, delay]);
|
|
@@ -7729,20 +9654,20 @@ function DataTable({
|
|
|
7729
9654
|
labels
|
|
7730
9655
|
}) {
|
|
7731
9656
|
const t = (0, import_next_intl7.useTranslations)("Common");
|
|
7732
|
-
const [visibleCols, setVisibleCols] =
|
|
7733
|
-
const [filters, setFilters] =
|
|
7734
|
-
const [sort, setSort] =
|
|
7735
|
-
const [density, setDensity] =
|
|
7736
|
-
const [curPage, setCurPage] =
|
|
7737
|
-
const [curPageSize, setCurPageSize] =
|
|
9657
|
+
const [visibleCols, setVisibleCols] = import_react23.default.useState(() => columns.filter((c) => c.visible !== false).map((c) => c.key));
|
|
9658
|
+
const [filters, setFilters] = import_react23.default.useState({});
|
|
9659
|
+
const [sort, setSort] = import_react23.default.useState(null);
|
|
9660
|
+
const [density, setDensity] = import_react23.default.useState("normal");
|
|
9661
|
+
const [curPage, setCurPage] = import_react23.default.useState(page);
|
|
9662
|
+
const [curPageSize, setCurPageSize] = import_react23.default.useState(pageSize);
|
|
7738
9663
|
const debouncedFilters = useDebounced(filters, 350);
|
|
7739
|
-
|
|
9664
|
+
import_react23.default.useEffect(() => {
|
|
7740
9665
|
setCurPage(page);
|
|
7741
9666
|
}, [page]);
|
|
7742
|
-
|
|
9667
|
+
import_react23.default.useEffect(() => {
|
|
7743
9668
|
setCurPageSize(pageSize);
|
|
7744
9669
|
}, [pageSize]);
|
|
7745
|
-
|
|
9670
|
+
import_react23.default.useEffect(() => {
|
|
7746
9671
|
if (!onQueryChange) return;
|
|
7747
9672
|
onQueryChange({ filters: debouncedFilters, sort, page: curPage, pageSize: curPageSize });
|
|
7748
9673
|
}, [debouncedFilters, sort, curPage, curPageSize]);
|
|
@@ -7761,7 +9686,7 @@ function DataTable({
|
|
|
7761
9686
|
className: "h-8 w-full text-sm"
|
|
7762
9687
|
};
|
|
7763
9688
|
if (col.filter.type === "text") {
|
|
7764
|
-
return /* @__PURE__ */ (0,
|
|
9689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7765
9690
|
Input_default,
|
|
7766
9691
|
{
|
|
7767
9692
|
...commonProps,
|
|
@@ -7776,7 +9701,7 @@ function DataTable({
|
|
|
7776
9701
|
}
|
|
7777
9702
|
if (col.filter.type === "select") {
|
|
7778
9703
|
const options = col.filter.options || [];
|
|
7779
|
-
return /* @__PURE__ */ (0,
|
|
9704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7780
9705
|
Combobox,
|
|
7781
9706
|
{
|
|
7782
9707
|
options: ["", ...options],
|
|
@@ -7792,7 +9717,7 @@ function DataTable({
|
|
|
7792
9717
|
);
|
|
7793
9718
|
}
|
|
7794
9719
|
if (col.filter.type === "date") {
|
|
7795
|
-
return /* @__PURE__ */ (0,
|
|
9720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7796
9721
|
DatePicker,
|
|
7797
9722
|
{
|
|
7798
9723
|
placeholder: col.filter.placeholder || `Select ${String(col.title)}`,
|
|
@@ -7806,7 +9731,7 @@ function DataTable({
|
|
|
7806
9731
|
}
|
|
7807
9732
|
return null;
|
|
7808
9733
|
};
|
|
7809
|
-
const renderHeader = /* @__PURE__ */ (0,
|
|
9734
|
+
const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableRow, { children: visibleColumns.map((col, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7810
9735
|
TableHead,
|
|
7811
9736
|
{
|
|
7812
9737
|
style: { width: col.width },
|
|
@@ -7815,10 +9740,10 @@ function DataTable({
|
|
|
7815
9740
|
col.align === "center" && "text-center",
|
|
7816
9741
|
columnDividers && colIdx > 0 && "border-l border-border/60"
|
|
7817
9742
|
),
|
|
7818
|
-
children: /* @__PURE__ */ (0,
|
|
7819
|
-
/* @__PURE__ */ (0,
|
|
7820
|
-
/* @__PURE__ */ (0,
|
|
7821
|
-
col.sortable && /* @__PURE__ */ (0,
|
|
9743
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between gap-2 select-none min-h-[2.5rem]", children: [
|
|
9744
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1 min-w-0 flex-1", children: [
|
|
9745
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "truncate font-medium text-sm", children: col.title }),
|
|
9746
|
+
col.sortable && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7822
9747
|
"button",
|
|
7823
9748
|
{
|
|
7824
9749
|
className: cn(
|
|
@@ -7835,8 +9760,8 @@ function DataTable({
|
|
|
7835
9760
|
},
|
|
7836
9761
|
"aria-label": "Sort",
|
|
7837
9762
|
title: `Sort by ${String(col.title)}`,
|
|
7838
|
-
children: /* @__PURE__ */ (0,
|
|
7839
|
-
/* @__PURE__ */ (0,
|
|
9763
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
|
|
9764
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7840
9765
|
"path",
|
|
7841
9766
|
{
|
|
7842
9767
|
d: "M7 8l3-3 3 3",
|
|
@@ -7847,7 +9772,7 @@ function DataTable({
|
|
|
7847
9772
|
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
7848
9773
|
}
|
|
7849
9774
|
),
|
|
7850
|
-
/* @__PURE__ */ (0,
|
|
9775
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7851
9776
|
"path",
|
|
7852
9777
|
{
|
|
7853
9778
|
d: "M7 12l3 3 3-3",
|
|
@@ -7862,11 +9787,11 @@ function DataTable({
|
|
|
7862
9787
|
}
|
|
7863
9788
|
)
|
|
7864
9789
|
] }),
|
|
7865
|
-
col.filter && /* @__PURE__ */ (0,
|
|
9790
|
+
col.filter && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7866
9791
|
Popover,
|
|
7867
9792
|
{
|
|
7868
9793
|
placement: "bottom-start",
|
|
7869
|
-
trigger: /* @__PURE__ */ (0,
|
|
9794
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7870
9795
|
"button",
|
|
7871
9796
|
{
|
|
7872
9797
|
className: cn(
|
|
@@ -7876,16 +9801,16 @@ function DataTable({
|
|
|
7876
9801
|
),
|
|
7877
9802
|
"aria-label": "Filter",
|
|
7878
9803
|
title: "Filter",
|
|
7879
|
-
children: /* @__PURE__ */ (0,
|
|
9804
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react26.Filter, { className: "h-4 w-4" })
|
|
7880
9805
|
}
|
|
7881
9806
|
),
|
|
7882
|
-
children: /* @__PURE__ */ (0,
|
|
7883
|
-
/* @__PURE__ */ (0,
|
|
9807
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "w-48 p-2 space-y-2", children: [
|
|
9808
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
|
|
7884
9809
|
"Filter ",
|
|
7885
9810
|
col.title
|
|
7886
9811
|
] }),
|
|
7887
9812
|
renderFilterControl(col),
|
|
7888
|
-
filters[col.key] && /* @__PURE__ */ (0,
|
|
9813
|
+
filters[col.key] && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7889
9814
|
"button",
|
|
7890
9815
|
{
|
|
7891
9816
|
onClick: () => {
|
|
@@ -7908,20 +9833,20 @@ function DataTable({
|
|
|
7908
9833
|
col.key
|
|
7909
9834
|
)) });
|
|
7910
9835
|
const isServerMode = Boolean(onQueryChange);
|
|
7911
|
-
const displayedData = isServerMode ? data :
|
|
9836
|
+
const displayedData = isServerMode ? data : import_react23.default.useMemo(() => {
|
|
7912
9837
|
const start = (curPage - 1) * curPageSize;
|
|
7913
9838
|
return data.slice(start, start + curPageSize);
|
|
7914
9839
|
}, [data, curPage, curPageSize]);
|
|
7915
9840
|
const totalItems = isServerMode ? total : data.length;
|
|
7916
|
-
return /* @__PURE__ */ (0,
|
|
7917
|
-
/* @__PURE__ */ (0,
|
|
7918
|
-
/* @__PURE__ */ (0,
|
|
7919
|
-
/* @__PURE__ */ (0,
|
|
7920
|
-
enableDensityToggle && /* @__PURE__ */ (0,
|
|
9841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn("space-y-2", className), children: [
|
|
9842
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
|
|
9843
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "text-sm text-muted-foreground", children: caption }),
|
|
9844
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9845
|
+
enableDensityToggle && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7921
9846
|
DropdownMenu_default,
|
|
7922
9847
|
{
|
|
7923
|
-
trigger: /* @__PURE__ */ (0,
|
|
7924
|
-
/* @__PURE__ */ (0,
|
|
9848
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
|
|
9849
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
7925
9850
|
labels?.density || t("density")
|
|
7926
9851
|
] }),
|
|
7927
9852
|
items: [
|
|
@@ -7931,11 +9856,11 @@ function DataTable({
|
|
|
7931
9856
|
]
|
|
7932
9857
|
}
|
|
7933
9858
|
),
|
|
7934
|
-
enableColumnVisibilityToggle && /* @__PURE__ */ (0,
|
|
9859
|
+
enableColumnVisibilityToggle && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7935
9860
|
DropdownMenu_default,
|
|
7936
9861
|
{
|
|
7937
|
-
trigger: /* @__PURE__ */ (0,
|
|
7938
|
-
/* @__PURE__ */ (0,
|
|
9862
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
|
|
9863
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7939
9864
|
"path",
|
|
7940
9865
|
{
|
|
7941
9866
|
strokeLinecap: "round",
|
|
@@ -7946,15 +9871,15 @@ function DataTable({
|
|
|
7946
9871
|
) }),
|
|
7947
9872
|
labels?.columns || t("columns")
|
|
7948
9873
|
] }),
|
|
7949
|
-
children: columns.map((c) => /* @__PURE__ */ (0,
|
|
9874
|
+
children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
7950
9875
|
DropdownMenuItem,
|
|
7951
9876
|
{
|
|
7952
9877
|
onClick: () => {
|
|
7953
9878
|
setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
|
|
7954
9879
|
},
|
|
7955
9880
|
children: [
|
|
7956
|
-
/* @__PURE__ */ (0,
|
|
7957
|
-
/* @__PURE__ */ (0,
|
|
9881
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("input", { type: "checkbox", className: "mr-2 rounded border-border", readOnly: true, checked: visibleCols.includes(c.key) }),
|
|
9882
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "truncate", children: c.title })
|
|
7958
9883
|
]
|
|
7959
9884
|
},
|
|
7960
9885
|
c.key
|
|
@@ -7964,17 +9889,17 @@ function DataTable({
|
|
|
7964
9889
|
toolbar
|
|
7965
9890
|
] })
|
|
7966
9891
|
] }),
|
|
7967
|
-
/* @__PURE__ */ (0,
|
|
9892
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: cn("relative rounded-md border border-border/50 overflow-hidden", loading2 && "opacity-60 pointer-events-none"), children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
7968
9893
|
Table,
|
|
7969
9894
|
{
|
|
7970
9895
|
containerClassName: "border-0 md:border-0 rounded-none md:rounded-none shadow-none bg-transparent",
|
|
7971
9896
|
className: "[&_thead]:sticky [&_thead]:top-0 [&_thead]:z-[5] [&_thead]:bg-background [&_thead]:backdrop-blur-sm",
|
|
7972
9897
|
children: [
|
|
7973
|
-
/* @__PURE__ */ (0,
|
|
7974
|
-
/* @__PURE__ */ (0,
|
|
7975
|
-
/* @__PURE__ */ (0,
|
|
7976
|
-
/* @__PURE__ */ (0,
|
|
7977
|
-
/* @__PURE__ */ (0,
|
|
9898
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableHeader, { children: renderHeader }),
|
|
9899
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
|
|
9900
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
9901
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
9902
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7978
9903
|
"path",
|
|
7979
9904
|
{
|
|
7980
9905
|
className: "opacity-75",
|
|
@@ -7983,10 +9908,10 @@ function DataTable({
|
|
|
7983
9908
|
}
|
|
7984
9909
|
)
|
|
7985
9910
|
] }),
|
|
7986
|
-
/* @__PURE__ */ (0,
|
|
7987
|
-
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0,
|
|
9911
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-sm", children: "Loading..." })
|
|
9912
|
+
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: "No data" }) }) : displayedData.map((row, idx) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TableRow, { className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/30"), children: visibleColumns.map((col, colIdx) => {
|
|
7988
9913
|
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
7989
|
-
return /* @__PURE__ */ (0,
|
|
9914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
7990
9915
|
TableCell,
|
|
7991
9916
|
{
|
|
7992
9917
|
className: cn(
|
|
@@ -8005,7 +9930,7 @@ function DataTable({
|
|
|
8005
9930
|
]
|
|
8006
9931
|
}
|
|
8007
9932
|
) }),
|
|
8008
|
-
totalItems > 0 && /* @__PURE__ */ (0,
|
|
9933
|
+
totalItems > 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t bg-muted/30 p-4 rounded-b-md", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
8009
9934
|
Pagination,
|
|
8010
9935
|
{
|
|
8011
9936
|
page: curPage,
|
|
@@ -8027,10 +9952,10 @@ function DataTable({
|
|
|
8027
9952
|
var DataTable_default = DataTable;
|
|
8028
9953
|
|
|
8029
9954
|
// ../../components/ui/Form.tsx
|
|
8030
|
-
var
|
|
9955
|
+
var React39 = __toESM(require("react"), 1);
|
|
8031
9956
|
|
|
8032
9957
|
// ../../node_modules/react-hook-form/dist/index.esm.mjs
|
|
8033
|
-
var
|
|
9958
|
+
var import_react24 = __toESM(require("react"), 1);
|
|
8034
9959
|
var isCheckBoxInput = (element) => element.type === "checkbox";
|
|
8035
9960
|
var isDateObject = (value) => value instanceof Date;
|
|
8036
9961
|
var isNullOrUndefined = (value) => value == null;
|
|
@@ -8118,12 +10043,12 @@ var INPUT_VALIDATION_RULES = {
|
|
|
8118
10043
|
required: "required",
|
|
8119
10044
|
validate: "validate"
|
|
8120
10045
|
};
|
|
8121
|
-
var HookFormContext =
|
|
10046
|
+
var HookFormContext = import_react24.default.createContext(null);
|
|
8122
10047
|
HookFormContext.displayName = "HookFormContext";
|
|
8123
|
-
var useFormContext = () =>
|
|
10048
|
+
var useFormContext = () => import_react24.default.useContext(HookFormContext);
|
|
8124
10049
|
var FormProvider = (props) => {
|
|
8125
10050
|
const { children, ...data } = props;
|
|
8126
|
-
return
|
|
10051
|
+
return import_react24.default.createElement(HookFormContext.Provider, { value: data }, children);
|
|
8127
10052
|
};
|
|
8128
10053
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
8129
10054
|
const result = {
|
|
@@ -8143,12 +10068,12 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
|
8143
10068
|
}
|
|
8144
10069
|
return result;
|
|
8145
10070
|
};
|
|
8146
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
10071
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react24.default.useLayoutEffect : import_react24.default.useEffect;
|
|
8147
10072
|
function useFormState(props) {
|
|
8148
10073
|
const methods = useFormContext();
|
|
8149
10074
|
const { control = methods.control, disabled, name, exact } = props || {};
|
|
8150
|
-
const [formState, updateFormState] =
|
|
8151
|
-
const _localProxyFormState =
|
|
10075
|
+
const [formState, updateFormState] = import_react24.default.useState(control._formState);
|
|
10076
|
+
const _localProxyFormState = import_react24.default.useRef({
|
|
8152
10077
|
isDirty: false,
|
|
8153
10078
|
isLoading: false,
|
|
8154
10079
|
dirtyFields: false,
|
|
@@ -8169,10 +10094,10 @@ function useFormState(props) {
|
|
|
8169
10094
|
});
|
|
8170
10095
|
}
|
|
8171
10096
|
}), [name, disabled, exact]);
|
|
8172
|
-
|
|
10097
|
+
import_react24.default.useEffect(() => {
|
|
8173
10098
|
_localProxyFormState.current.isValid && control._setValid(true);
|
|
8174
10099
|
}, [control]);
|
|
8175
|
-
return
|
|
10100
|
+
return import_react24.default.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
|
|
8176
10101
|
}
|
|
8177
10102
|
var isString = (value) => typeof value === "string";
|
|
8178
10103
|
var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
|
|
@@ -8221,12 +10146,12 @@ function deepEqual(object1, object2, _internal_visited = /* @__PURE__ */ new Wea
|
|
|
8221
10146
|
function useWatch(props) {
|
|
8222
10147
|
const methods = useFormContext();
|
|
8223
10148
|
const { control = methods.control, name, defaultValue, disabled, exact, compute } = props || {};
|
|
8224
|
-
const _defaultValue =
|
|
8225
|
-
const _compute =
|
|
8226
|
-
const _computeFormValues =
|
|
10149
|
+
const _defaultValue = import_react24.default.useRef(defaultValue);
|
|
10150
|
+
const _compute = import_react24.default.useRef(compute);
|
|
10151
|
+
const _computeFormValues = import_react24.default.useRef(void 0);
|
|
8227
10152
|
_compute.current = compute;
|
|
8228
|
-
const defaultValueMemo =
|
|
8229
|
-
const [value, updateValue] =
|
|
10153
|
+
const defaultValueMemo = import_react24.default.useMemo(() => control._getWatch(name, _defaultValue.current), [control, name]);
|
|
10154
|
+
const [value, updateValue] = import_react24.default.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo);
|
|
8230
10155
|
useIsomorphicLayoutEffect(() => control._subscribe({
|
|
8231
10156
|
name,
|
|
8232
10157
|
formState: {
|
|
@@ -8248,14 +10173,14 @@ function useWatch(props) {
|
|
|
8248
10173
|
}
|
|
8249
10174
|
}
|
|
8250
10175
|
}), [control, disabled, name, exact]);
|
|
8251
|
-
|
|
10176
|
+
import_react24.default.useEffect(() => control._removeUnmounted());
|
|
8252
10177
|
return value;
|
|
8253
10178
|
}
|
|
8254
10179
|
function useController(props) {
|
|
8255
10180
|
const methods = useFormContext();
|
|
8256
10181
|
const { name, disabled, control = methods.control, shouldUnregister, defaultValue } = props;
|
|
8257
10182
|
const isArrayField = isNameInFieldArray(control._names.array, name);
|
|
8258
|
-
const defaultValueMemo =
|
|
10183
|
+
const defaultValueMemo = import_react24.default.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
|
8259
10184
|
const value = useWatch({
|
|
8260
10185
|
control,
|
|
8261
10186
|
name,
|
|
@@ -8267,15 +10192,15 @@ function useController(props) {
|
|
|
8267
10192
|
name,
|
|
8268
10193
|
exact: true
|
|
8269
10194
|
});
|
|
8270
|
-
const _props =
|
|
8271
|
-
const _previousNameRef =
|
|
8272
|
-
const _registerProps =
|
|
10195
|
+
const _props = import_react24.default.useRef(props);
|
|
10196
|
+
const _previousNameRef = import_react24.default.useRef(void 0);
|
|
10197
|
+
const _registerProps = import_react24.default.useRef(control.register(name, {
|
|
8273
10198
|
...props.rules,
|
|
8274
10199
|
value,
|
|
8275
10200
|
...isBoolean(props.disabled) ? { disabled: props.disabled } : {}
|
|
8276
10201
|
}));
|
|
8277
10202
|
_props.current = props;
|
|
8278
|
-
const fieldState =
|
|
10203
|
+
const fieldState = import_react24.default.useMemo(() => Object.defineProperties({}, {
|
|
8279
10204
|
invalid: {
|
|
8280
10205
|
enumerable: true,
|
|
8281
10206
|
get: () => !!get(formState.errors, name)
|
|
@@ -8297,21 +10222,21 @@ function useController(props) {
|
|
|
8297
10222
|
get: () => get(formState.errors, name)
|
|
8298
10223
|
}
|
|
8299
10224
|
}), [formState, name]);
|
|
8300
|
-
const onChange =
|
|
10225
|
+
const onChange = import_react24.default.useCallback((event) => _registerProps.current.onChange({
|
|
8301
10226
|
target: {
|
|
8302
10227
|
value: getEventValue(event),
|
|
8303
10228
|
name
|
|
8304
10229
|
},
|
|
8305
10230
|
type: EVENTS.CHANGE
|
|
8306
10231
|
}), [name]);
|
|
8307
|
-
const onBlur =
|
|
10232
|
+
const onBlur = import_react24.default.useCallback(() => _registerProps.current.onBlur({
|
|
8308
10233
|
target: {
|
|
8309
10234
|
value: get(control._formValues, name),
|
|
8310
10235
|
name
|
|
8311
10236
|
},
|
|
8312
10237
|
type: EVENTS.BLUR
|
|
8313
10238
|
}), [name, control._formValues]);
|
|
8314
|
-
const ref =
|
|
10239
|
+
const ref = import_react24.default.useCallback((elm) => {
|
|
8315
10240
|
const field2 = get(control._fields, name);
|
|
8316
10241
|
if (field2 && elm) {
|
|
8317
10242
|
field2._f.ref = {
|
|
@@ -8322,7 +10247,7 @@ function useController(props) {
|
|
|
8322
10247
|
};
|
|
8323
10248
|
}
|
|
8324
10249
|
}, [control._fields, name]);
|
|
8325
|
-
const field =
|
|
10250
|
+
const field = import_react24.default.useMemo(() => ({
|
|
8326
10251
|
name,
|
|
8327
10252
|
value,
|
|
8328
10253
|
...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {},
|
|
@@ -8330,7 +10255,7 @@ function useController(props) {
|
|
|
8330
10255
|
onBlur,
|
|
8331
10256
|
ref
|
|
8332
10257
|
}), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
|
|
8333
|
-
|
|
10258
|
+
import_react24.default.useEffect(() => {
|
|
8334
10259
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
|
8335
10260
|
const previousName = _previousNameRef.current;
|
|
8336
10261
|
if (previousName && previousName !== name && !isArrayField) {
|
|
@@ -8360,13 +10285,13 @@ function useController(props) {
|
|
|
8360
10285
|
(isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false);
|
|
8361
10286
|
};
|
|
8362
10287
|
}, [name, control, isArrayField, shouldUnregister]);
|
|
8363
|
-
|
|
10288
|
+
import_react24.default.useEffect(() => {
|
|
8364
10289
|
control._setDisabledField({
|
|
8365
10290
|
disabled,
|
|
8366
10291
|
name
|
|
8367
10292
|
});
|
|
8368
10293
|
}, [disabled, name, control]);
|
|
8369
|
-
return
|
|
10294
|
+
return import_react24.default.useMemo(() => ({
|
|
8370
10295
|
field,
|
|
8371
10296
|
formState,
|
|
8372
10297
|
fieldState
|
|
@@ -9685,9 +11610,9 @@ function createFormControl(props = {}) {
|
|
|
9685
11610
|
};
|
|
9686
11611
|
}
|
|
9687
11612
|
function useForm(props = {}) {
|
|
9688
|
-
const _formControl =
|
|
9689
|
-
const _values =
|
|
9690
|
-
const [formState, updateFormState] =
|
|
11613
|
+
const _formControl = import_react24.default.useRef(void 0);
|
|
11614
|
+
const _values = import_react24.default.useRef(void 0);
|
|
11615
|
+
const [formState, updateFormState] = import_react24.default.useState({
|
|
9691
11616
|
isDirty: false,
|
|
9692
11617
|
isValidating: false,
|
|
9693
11618
|
isLoading: isFunction(props.defaultValues),
|
|
@@ -9736,8 +11661,8 @@ function useForm(props = {}) {
|
|
|
9736
11661
|
control._formState.isReady = true;
|
|
9737
11662
|
return sub;
|
|
9738
11663
|
}, [control]);
|
|
9739
|
-
|
|
9740
|
-
|
|
11664
|
+
import_react24.default.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
|
11665
|
+
import_react24.default.useEffect(() => {
|
|
9741
11666
|
if (props.mode) {
|
|
9742
11667
|
control._options.mode = props.mode;
|
|
9743
11668
|
}
|
|
@@ -9745,18 +11670,18 @@ function useForm(props = {}) {
|
|
|
9745
11670
|
control._options.reValidateMode = props.reValidateMode;
|
|
9746
11671
|
}
|
|
9747
11672
|
}, [control, props.mode, props.reValidateMode]);
|
|
9748
|
-
|
|
11673
|
+
import_react24.default.useEffect(() => {
|
|
9749
11674
|
if (props.errors) {
|
|
9750
11675
|
control._setErrors(props.errors);
|
|
9751
11676
|
control._focusError();
|
|
9752
11677
|
}
|
|
9753
11678
|
}, [control, props.errors]);
|
|
9754
|
-
|
|
11679
|
+
import_react24.default.useEffect(() => {
|
|
9755
11680
|
props.shouldUnregister && control._subjects.state.next({
|
|
9756
11681
|
values: control._getWatch()
|
|
9757
11682
|
});
|
|
9758
11683
|
}, [control, props.shouldUnregister]);
|
|
9759
|
-
|
|
11684
|
+
import_react24.default.useEffect(() => {
|
|
9760
11685
|
if (control._proxyFormState.isDirty) {
|
|
9761
11686
|
const isDirty = control._getDirty();
|
|
9762
11687
|
if (isDirty !== formState.isDirty) {
|
|
@@ -9766,7 +11691,7 @@ function useForm(props = {}) {
|
|
|
9766
11691
|
}
|
|
9767
11692
|
}
|
|
9768
11693
|
}, [control, formState.isDirty]);
|
|
9769
|
-
|
|
11694
|
+
import_react24.default.useEffect(() => {
|
|
9770
11695
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
|
9771
11696
|
control._reset(props.values, {
|
|
9772
11697
|
keepFieldsRef: true,
|
|
@@ -9778,7 +11703,7 @@ function useForm(props = {}) {
|
|
|
9778
11703
|
control._resetDefaultValues();
|
|
9779
11704
|
}
|
|
9780
11705
|
}, [control, props.values]);
|
|
9781
|
-
|
|
11706
|
+
import_react24.default.useEffect(() => {
|
|
9782
11707
|
if (!control._state.mount) {
|
|
9783
11708
|
control._setValid();
|
|
9784
11709
|
control._state.mount = true;
|
|
@@ -9795,8 +11720,8 @@ function useForm(props = {}) {
|
|
|
9795
11720
|
|
|
9796
11721
|
// ../../components/ui/Form.tsx
|
|
9797
11722
|
var import_next_intl8 = require("next-intl");
|
|
9798
|
-
var
|
|
9799
|
-
var FormConfigContext =
|
|
11723
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
11724
|
+
var FormConfigContext = React39.createContext({ size: "md" });
|
|
9800
11725
|
var FormWrapper = ({
|
|
9801
11726
|
children,
|
|
9802
11727
|
onSubmit,
|
|
@@ -9809,24 +11734,24 @@ var FormWrapper = ({
|
|
|
9809
11734
|
const methods = useForm({
|
|
9810
11735
|
defaultValues: initialValues
|
|
9811
11736
|
});
|
|
9812
|
-
|
|
11737
|
+
React39.useEffect(() => {
|
|
9813
11738
|
if (initialValues) {
|
|
9814
11739
|
methods.reset(initialValues);
|
|
9815
11740
|
}
|
|
9816
11741
|
}, [JSON.stringify(initialValues)]);
|
|
9817
11742
|
const { validationSchema: _, ...formProps } = props;
|
|
9818
|
-
return /* @__PURE__ */ (0,
|
|
11743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormProvider, { ...methods, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
|
|
9819
11744
|
};
|
|
9820
11745
|
var Form = FormWrapper;
|
|
9821
|
-
var FormFieldContext =
|
|
11746
|
+
var FormFieldContext = React39.createContext({});
|
|
9822
11747
|
var FormField = ({
|
|
9823
11748
|
...props
|
|
9824
11749
|
}) => {
|
|
9825
|
-
return /* @__PURE__ */ (0,
|
|
11750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Controller, { ...props }) });
|
|
9826
11751
|
};
|
|
9827
11752
|
var useFormField = () => {
|
|
9828
|
-
const fieldContext =
|
|
9829
|
-
const itemContext =
|
|
11753
|
+
const fieldContext = React39.useContext(FormFieldContext);
|
|
11754
|
+
const itemContext = React39.useContext(FormItemContext);
|
|
9830
11755
|
const { getFieldState, formState } = useFormContext();
|
|
9831
11756
|
if (!fieldContext) {
|
|
9832
11757
|
try {
|
|
@@ -9847,22 +11772,22 @@ var useFormField = () => {
|
|
|
9847
11772
|
...fieldState
|
|
9848
11773
|
};
|
|
9849
11774
|
};
|
|
9850
|
-
var FormItemContext =
|
|
9851
|
-
var FormItem =
|
|
9852
|
-
const id =
|
|
9853
|
-
return /* @__PURE__ */ (0,
|
|
11775
|
+
var FormItemContext = React39.createContext({});
|
|
11776
|
+
var FormItem = React39.forwardRef(({ className, ...props }, ref) => {
|
|
11777
|
+
const id = React39.useId();
|
|
11778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
9854
11779
|
});
|
|
9855
11780
|
FormItem.displayName = "FormItem";
|
|
9856
|
-
var FormLabel =
|
|
11781
|
+
var FormLabel = React39.forwardRef(({ className, ...props }, ref) => {
|
|
9857
11782
|
const { error, formItemId } = useFormField();
|
|
9858
|
-
const config =
|
|
11783
|
+
const config = React39.useContext(FormConfigContext);
|
|
9859
11784
|
const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
|
|
9860
|
-
return /* @__PURE__ */ (0,
|
|
11785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props });
|
|
9861
11786
|
});
|
|
9862
11787
|
FormLabel.displayName = "FormLabel";
|
|
9863
|
-
var FormControl =
|
|
11788
|
+
var FormControl = React39.forwardRef(({ ...props }, ref) => {
|
|
9864
11789
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
9865
|
-
return /* @__PURE__ */ (0,
|
|
11790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9866
11791
|
"div",
|
|
9867
11792
|
{
|
|
9868
11793
|
ref,
|
|
@@ -9874,37 +11799,37 @@ var FormControl = React32.forwardRef(({ ...props }, ref) => {
|
|
|
9874
11799
|
);
|
|
9875
11800
|
});
|
|
9876
11801
|
FormControl.displayName = "FormControl";
|
|
9877
|
-
var FormDescription =
|
|
11802
|
+
var FormDescription = React39.forwardRef(({ className, ...props }, ref) => {
|
|
9878
11803
|
const { formDescriptionId } = useFormField();
|
|
9879
|
-
return /* @__PURE__ */ (0,
|
|
11804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
|
|
9880
11805
|
});
|
|
9881
11806
|
FormDescription.displayName = "FormDescription";
|
|
9882
|
-
var FormMessage =
|
|
11807
|
+
var FormMessage = React39.forwardRef(({ className, children, ...props }, ref) => {
|
|
9883
11808
|
const { error, formMessageId } = useFormField();
|
|
9884
11809
|
const body = error ? String(error?.message) : children;
|
|
9885
11810
|
if (!body) {
|
|
9886
11811
|
return null;
|
|
9887
11812
|
}
|
|
9888
|
-
return /* @__PURE__ */ (0,
|
|
11813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
|
|
9889
11814
|
});
|
|
9890
11815
|
FormMessage.displayName = "FormMessage";
|
|
9891
|
-
var FormInput =
|
|
11816
|
+
var FormInput = React39.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9892
11817
|
FormField,
|
|
9893
11818
|
{
|
|
9894
11819
|
name,
|
|
9895
|
-
render: ({ field }) => /* @__PURE__ */ (0,
|
|
9896
|
-
/* @__PURE__ */ (0,
|
|
9897
|
-
/* @__PURE__ */ (0,
|
|
11820
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(FormItem, { children: [
|
|
11821
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Input_default, { size: props.size ?? size, ...field, ...props }) }),
|
|
11822
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormMessage, {})
|
|
9898
11823
|
] })
|
|
9899
11824
|
}
|
|
9900
11825
|
) }));
|
|
9901
11826
|
FormInput.displayName = "FormInput";
|
|
9902
|
-
var FormCheckbox =
|
|
11827
|
+
var FormCheckbox = React39.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9903
11828
|
FormField,
|
|
9904
11829
|
{
|
|
9905
11830
|
name,
|
|
9906
|
-
render: ({ field }) => /* @__PURE__ */ (0,
|
|
9907
|
-
/* @__PURE__ */ (0,
|
|
11831
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(FormItem, { children: [
|
|
11832
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9908
11833
|
Checkbox,
|
|
9909
11834
|
{
|
|
9910
11835
|
ref,
|
|
@@ -9918,24 +11843,24 @@ var FormCheckbox = React32.forwardRef(({ name, ...props }, ref) => /* @__PURE__
|
|
|
9918
11843
|
...props
|
|
9919
11844
|
}
|
|
9920
11845
|
) }),
|
|
9921
|
-
/* @__PURE__ */ (0,
|
|
11846
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormMessage, {})
|
|
9922
11847
|
] })
|
|
9923
11848
|
}
|
|
9924
11849
|
) }));
|
|
9925
11850
|
FormCheckbox.displayName = "FormCheckbox";
|
|
9926
|
-
var FormActions =
|
|
11851
|
+
var FormActions = React39.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
|
|
9927
11852
|
FormActions.displayName = "FormActions";
|
|
9928
|
-
var FormSubmitButton =
|
|
11853
|
+
var FormSubmitButton = React39.forwardRef(({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) }));
|
|
9929
11854
|
FormSubmitButton.displayName = "FormSubmitButton";
|
|
9930
11855
|
|
|
9931
11856
|
// ../../components/ui/NotificationModal.tsx
|
|
9932
|
-
var
|
|
11857
|
+
var import_lucide_react27 = require("lucide-react");
|
|
9933
11858
|
var import_next_intl9 = require("next-intl");
|
|
9934
|
-
var
|
|
11859
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
9935
11860
|
function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
|
|
9936
11861
|
const t = (0, import_next_intl9.useTranslations)("Common");
|
|
9937
11862
|
if (!notification) return null;
|
|
9938
|
-
const
|
|
11863
|
+
const formatTime3 = (dateString) => {
|
|
9939
11864
|
const date = new Date(dateString);
|
|
9940
11865
|
return date.toLocaleString(void 0, {
|
|
9941
11866
|
year: "numeric",
|
|
@@ -9952,26 +11877,26 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
|
|
|
9952
11877
|
onClose();
|
|
9953
11878
|
}
|
|
9954
11879
|
};
|
|
9955
|
-
return /* @__PURE__ */ (0,
|
|
11880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9956
11881
|
Modal_default,
|
|
9957
11882
|
{
|
|
9958
11883
|
isOpen,
|
|
9959
11884
|
onClose,
|
|
9960
11885
|
title: titleText || t("notifications"),
|
|
9961
11886
|
size: "md",
|
|
9962
|
-
children: /* @__PURE__ */ (0,
|
|
9963
|
-
/* @__PURE__ */ (0,
|
|
9964
|
-
/* @__PURE__ */ (0,
|
|
11887
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "space-y-4", children: [
|
|
11888
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
|
|
11889
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: cn(
|
|
9965
11890
|
"w-2 h-2 rounded-full",
|
|
9966
11891
|
!notification.is_read ? "bg-primary" : "bg-border"
|
|
9967
11892
|
) }),
|
|
9968
|
-
/* @__PURE__ */ (0,
|
|
11893
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
|
|
9969
11894
|
] }),
|
|
9970
|
-
notification.title && /* @__PURE__ */ (0,
|
|
9971
|
-
notification.body && /* @__PURE__ */ (0,
|
|
9972
|
-
/* @__PURE__ */ (0,
|
|
9973
|
-
/* @__PURE__ */ (0,
|
|
9974
|
-
hasLink && /* @__PURE__ */ (0,
|
|
11895
|
+
notification.title && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
|
|
11896
|
+
notification.body && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
|
|
11897
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
|
|
11898
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex gap-2 justify-end pt-2", children: [
|
|
11899
|
+
hasLink && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
9975
11900
|
Button_default,
|
|
9976
11901
|
{
|
|
9977
11902
|
variant: "primary",
|
|
@@ -9979,12 +11904,12 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
|
|
|
9979
11904
|
onClick: handleLinkClick,
|
|
9980
11905
|
className: "gap-2",
|
|
9981
11906
|
children: [
|
|
9982
|
-
/* @__PURE__ */ (0,
|
|
11907
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react27.ExternalLink, { className: "w-4 h-4" }),
|
|
9983
11908
|
openLinkText || t("openLink")
|
|
9984
11909
|
]
|
|
9985
11910
|
}
|
|
9986
11911
|
),
|
|
9987
|
-
/* @__PURE__ */ (0,
|
|
11912
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
9988
11913
|
Button_default,
|
|
9989
11914
|
{
|
|
9990
11915
|
variant: "ghost",
|
|
@@ -10003,13 +11928,13 @@ var NotificationModal_default = NotificationModal;
|
|
|
10003
11928
|
// ../../components/ui/FloatingContacts.tsx
|
|
10004
11929
|
var import_link2 = __toESM(require("next/link"), 1);
|
|
10005
11930
|
var import_navigation = require("next/navigation");
|
|
10006
|
-
var
|
|
11931
|
+
var import_lucide_react28 = require("lucide-react");
|
|
10007
11932
|
|
|
10008
11933
|
// ../../node_modules/react-icons/lib/iconBase.mjs
|
|
10009
|
-
var
|
|
11934
|
+
var import_react26 = __toESM(require("react"), 1);
|
|
10010
11935
|
|
|
10011
11936
|
// ../../node_modules/react-icons/lib/iconContext.mjs
|
|
10012
|
-
var
|
|
11937
|
+
var import_react25 = __toESM(require("react"), 1);
|
|
10013
11938
|
var DefaultContext = {
|
|
10014
11939
|
color: void 0,
|
|
10015
11940
|
size: void 0,
|
|
@@ -10017,7 +11942,7 @@ var DefaultContext = {
|
|
|
10017
11942
|
style: void 0,
|
|
10018
11943
|
attr: void 0
|
|
10019
11944
|
};
|
|
10020
|
-
var IconContext =
|
|
11945
|
+
var IconContext = import_react25.default.createContext && /* @__PURE__ */ import_react25.default.createContext(DefaultContext);
|
|
10021
11946
|
|
|
10022
11947
|
// ../../node_modules/react-icons/lib/iconBase.mjs
|
|
10023
11948
|
var _excluded = ["attr", "size", "title"];
|
|
@@ -10106,12 +12031,12 @@ function _toPrimitive(t, r) {
|
|
|
10106
12031
|
return ("string" === r ? String : Number)(t);
|
|
10107
12032
|
}
|
|
10108
12033
|
function Tree2Element(tree) {
|
|
10109
|
-
return tree && tree.map((node, i) => /* @__PURE__ */
|
|
12034
|
+
return tree && tree.map((node, i) => /* @__PURE__ */ import_react26.default.createElement(node.tag, _objectSpread({
|
|
10110
12035
|
key: i
|
|
10111
12036
|
}, node.attr), Tree2Element(node.child)));
|
|
10112
12037
|
}
|
|
10113
12038
|
function GenIcon(data) {
|
|
10114
|
-
return (props) => /* @__PURE__ */
|
|
12039
|
+
return (props) => /* @__PURE__ */ import_react26.default.createElement(IconBase, _extends({
|
|
10115
12040
|
attr: _objectSpread({}, data.attr)
|
|
10116
12041
|
}, props), Tree2Element(data.child));
|
|
10117
12042
|
}
|
|
@@ -10126,7 +12051,7 @@ function IconBase(props) {
|
|
|
10126
12051
|
var className;
|
|
10127
12052
|
if (conf.className) className = conf.className;
|
|
10128
12053
|
if (props.className) className = (className ? className + " " : "") + props.className;
|
|
10129
|
-
return /* @__PURE__ */
|
|
12054
|
+
return /* @__PURE__ */ import_react26.default.createElement("svg", _extends({
|
|
10130
12055
|
stroke: "currentColor",
|
|
10131
12056
|
fill: "currentColor",
|
|
10132
12057
|
strokeWidth: "0"
|
|
@@ -10138,9 +12063,9 @@ function IconBase(props) {
|
|
|
10138
12063
|
height: computedSize,
|
|
10139
12064
|
width: computedSize,
|
|
10140
12065
|
xmlns: "http://www.w3.org/2000/svg"
|
|
10141
|
-
}), title && /* @__PURE__ */
|
|
12066
|
+
}), title && /* @__PURE__ */ import_react26.default.createElement("title", null, title), props.children);
|
|
10142
12067
|
};
|
|
10143
|
-
return IconContext !== void 0 ? /* @__PURE__ */
|
|
12068
|
+
return IconContext !== void 0 ? /* @__PURE__ */ import_react26.default.createElement(IconContext.Consumer, null, (conf) => elem(conf)) : elem(DefaultContext);
|
|
10144
12069
|
}
|
|
10145
12070
|
|
|
10146
12071
|
// ../../node_modules/react-icons/fa/index.mjs
|
|
@@ -10154,9 +12079,9 @@ function SiZalo(props) {
|
|
|
10154
12079
|
}
|
|
10155
12080
|
|
|
10156
12081
|
// ../../components/ui/FloatingContacts.tsx
|
|
10157
|
-
var
|
|
12082
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
10158
12083
|
function MessengerIcon(props) {
|
|
10159
|
-
return /* @__PURE__ */ (0,
|
|
12084
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("svg", { viewBox: "0 0 24 24", width: 24, height: 24, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
10160
12085
|
"path",
|
|
10161
12086
|
{
|
|
10162
12087
|
d: "M12 2C6.477 2 2 6.145 2 11.235c0 2.93 1.35 5.542 3.464 7.25v3.515l3.344-1.836c.894.247 1.843.375 2.192.375 5.523 0 10-4.145 10-9.235S17.523 2 12 2zm.994 12.444l-2.563-2.73-5.004 2.73 5.507-5.84 2.626 2.729 4.942-2.729-5.508 5.84z",
|
|
@@ -10165,10 +12090,10 @@ function MessengerIcon(props) {
|
|
|
10165
12090
|
) });
|
|
10166
12091
|
}
|
|
10167
12092
|
function ZaloIcon(props) {
|
|
10168
|
-
return /* @__PURE__ */ (0,
|
|
12093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(SiZalo, { size: 20, ...props });
|
|
10169
12094
|
}
|
|
10170
12095
|
function InstagramIcon(props) {
|
|
10171
|
-
return /* @__PURE__ */ (0,
|
|
12096
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(FaInstagram, { size: 20, ...props });
|
|
10172
12097
|
}
|
|
10173
12098
|
function FloatingContacts({ className }) {
|
|
10174
12099
|
const pathname = (0, import_navigation.usePathname)();
|
|
@@ -10203,8 +12128,8 @@ function FloatingContacts({ className }) {
|
|
|
10203
12128
|
external: true
|
|
10204
12129
|
}
|
|
10205
12130
|
];
|
|
10206
|
-
return /* @__PURE__ */ (0,
|
|
10207
|
-
/* @__PURE__ */ (0,
|
|
12131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cn("fixed bottom-6 right-4 z-[100000]", "flex flex-col items-end gap-3", className), "aria-label": "Quick contacts", children: [
|
|
12132
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
10208
12133
|
import_link2.default,
|
|
10209
12134
|
{
|
|
10210
12135
|
href: `tel:${hotline.replace(/\D/g, "")}`,
|
|
@@ -10215,10 +12140,10 @@ function FloatingContacts({ className }) {
|
|
|
10215
12140
|
"hover:scale-105 active:scale-95 transition-transform",
|
|
10216
12141
|
"bg-[#22c55e]"
|
|
10217
12142
|
),
|
|
10218
|
-
children: /* @__PURE__ */ (0,
|
|
12143
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_lucide_react28.Phone, { className: "w-6 h-6" })
|
|
10219
12144
|
}
|
|
10220
12145
|
),
|
|
10221
|
-
moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0,
|
|
12146
|
+
moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
10222
12147
|
import_link2.default,
|
|
10223
12148
|
{
|
|
10224
12149
|
href,
|
|
@@ -10230,7 +12155,7 @@ function FloatingContacts({ className }) {
|
|
|
10230
12155
|
"hover:scale-105 active:scale-95 transition-transform",
|
|
10231
12156
|
bg
|
|
10232
12157
|
),
|
|
10233
|
-
children: /* @__PURE__ */ (0,
|
|
12158
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Icon, { className: "w-6 h-6" })
|
|
10234
12159
|
},
|
|
10235
12160
|
key
|
|
10236
12161
|
))
|
|
@@ -10238,17 +12163,17 @@ function FloatingContacts({ className }) {
|
|
|
10238
12163
|
}
|
|
10239
12164
|
|
|
10240
12165
|
// ../../components/ui/AccessDenied.tsx
|
|
10241
|
-
var
|
|
10242
|
-
var
|
|
12166
|
+
var import_lucide_react29 = require("lucide-react");
|
|
12167
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
10243
12168
|
var VARIANT_STYLES = {
|
|
10244
12169
|
destructive: { bg: "bg-destructive/5", border: "border-destructive/20", text: "text-destructive" },
|
|
10245
12170
|
warning: { bg: "bg-warning/5", border: "border-warning/20", text: "text-warning" },
|
|
10246
12171
|
info: { bg: "bg-info/5", border: "border-info/20", text: "text-info" }
|
|
10247
12172
|
};
|
|
10248
12173
|
var DEFAULT_ICONS = {
|
|
10249
|
-
destructive:
|
|
10250
|
-
warning:
|
|
10251
|
-
info:
|
|
12174
|
+
destructive: import_lucide_react29.ShieldAlert,
|
|
12175
|
+
warning: import_lucide_react29.Ban,
|
|
12176
|
+
info: import_lucide_react29.Lock
|
|
10252
12177
|
};
|
|
10253
12178
|
function AccessDenied({
|
|
10254
12179
|
title = "Access Restricted",
|
|
@@ -10260,36 +12185,36 @@ function AccessDenied({
|
|
|
10260
12185
|
}) {
|
|
10261
12186
|
const styles = VARIANT_STYLES[variant];
|
|
10262
12187
|
const UsedIcon = Icon || DEFAULT_ICONS[variant];
|
|
10263
|
-
return /* @__PURE__ */ (0,
|
|
10264
|
-
/* @__PURE__ */ (0,
|
|
10265
|
-
/* @__PURE__ */ (0,
|
|
10266
|
-
/* @__PURE__ */ (0,
|
|
10267
|
-
/* @__PURE__ */ (0,
|
|
12188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
12189
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
|
|
12190
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { children: [
|
|
12191
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
|
|
12192
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
|
|
10268
12193
|
] }),
|
|
10269
|
-
children && /* @__PURE__ */ (0,
|
|
12194
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
|
|
10270
12195
|
] }) });
|
|
10271
12196
|
}
|
|
10272
12197
|
|
|
10273
12198
|
// ../../components/ui/ThemeToggleHeadless.tsx
|
|
10274
|
-
var
|
|
10275
|
-
var
|
|
10276
|
-
var
|
|
10277
|
-
var
|
|
12199
|
+
var import_lucide_react30 = require("lucide-react");
|
|
12200
|
+
var import_react27 = require("react");
|
|
12201
|
+
var import_react_dom10 = require("react-dom");
|
|
12202
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
10278
12203
|
function ThemeToggleHeadless({
|
|
10279
12204
|
theme,
|
|
10280
12205
|
onChange,
|
|
10281
12206
|
labels,
|
|
10282
12207
|
className
|
|
10283
12208
|
}) {
|
|
10284
|
-
const [isOpen, setIsOpen] = (0,
|
|
10285
|
-
const [mounted, setMounted] = (0,
|
|
10286
|
-
const triggerRef = (0,
|
|
10287
|
-
const [dropdownPosition, setDropdownPosition] = (0,
|
|
10288
|
-
(0,
|
|
12209
|
+
const [isOpen, setIsOpen] = (0, import_react27.useState)(false);
|
|
12210
|
+
const [mounted, setMounted] = (0, import_react27.useState)(false);
|
|
12211
|
+
const triggerRef = (0, import_react27.useRef)(null);
|
|
12212
|
+
const [dropdownPosition, setDropdownPosition] = (0, import_react27.useState)(null);
|
|
12213
|
+
(0, import_react27.useEffect)(() => setMounted(true), []);
|
|
10289
12214
|
const themes = [
|
|
10290
|
-
{ value: "light", label: labels?.light ?? "Light", icon:
|
|
10291
|
-
{ value: "dark", label: labels?.dark ?? "Dark", icon:
|
|
10292
|
-
{ value: "system", label: labels?.system ?? "System", icon:
|
|
12215
|
+
{ value: "light", label: labels?.light ?? "Light", icon: import_lucide_react30.Sun },
|
|
12216
|
+
{ value: "dark", label: labels?.dark ?? "Dark", icon: import_lucide_react30.Moon },
|
|
12217
|
+
{ value: "system", label: labels?.system ?? "System", icon: import_lucide_react30.Monitor }
|
|
10293
12218
|
];
|
|
10294
12219
|
const current = mounted ? themes.find((t) => t.value === theme) || themes[2] : themes[2];
|
|
10295
12220
|
const CurrentIcon = current.icon;
|
|
@@ -10303,8 +12228,8 @@ function ThemeToggleHeadless({
|
|
|
10303
12228
|
const top = rect.bottom + scrollTop + 8;
|
|
10304
12229
|
return { top, left, width };
|
|
10305
12230
|
};
|
|
10306
|
-
return /* @__PURE__ */ (0,
|
|
10307
|
-
/* @__PURE__ */ (0,
|
|
12231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: cn("relative", className), children: [
|
|
12232
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
10308
12233
|
Button_default,
|
|
10309
12234
|
{
|
|
10310
12235
|
variant: "ghost",
|
|
@@ -10322,25 +12247,25 @@ function ThemeToggleHeadless({
|
|
|
10322
12247
|
"aria-haspopup": "menu",
|
|
10323
12248
|
"aria-expanded": isOpen,
|
|
10324
12249
|
"aria-label": labels?.heading ?? "Theme",
|
|
10325
|
-
children: /* @__PURE__ */ (0,
|
|
12250
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(CurrentIcon, { className: "h-5 w-5" })
|
|
10326
12251
|
}
|
|
10327
12252
|
),
|
|
10328
|
-
isOpen && /* @__PURE__ */ (0,
|
|
10329
|
-
typeof window !== "undefined" && (0,
|
|
10330
|
-
typeof window !== "undefined" && dropdownPosition && (0,
|
|
10331
|
-
/* @__PURE__ */ (0,
|
|
12253
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
|
|
12254
|
+
typeof window !== "undefined" && (0, import_react_dom10.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "fixed inset-0 z-[9998]", onClick: () => setIsOpen(false) }), document.body),
|
|
12255
|
+
typeof window !== "undefined" && dropdownPosition && (0, import_react_dom10.createPortal)(
|
|
12256
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
10332
12257
|
"div",
|
|
10333
12258
|
{
|
|
10334
12259
|
className: "z-[9999] bg-card border border-border rounded-lg shadow-lg overflow-hidden",
|
|
10335
12260
|
style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
|
|
10336
12261
|
onMouseDown: (e) => e.stopPropagation(),
|
|
10337
12262
|
role: "menu",
|
|
10338
|
-
children: /* @__PURE__ */ (0,
|
|
10339
|
-
/* @__PURE__ */ (0,
|
|
12263
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "p-2", children: [
|
|
12264
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
|
|
10340
12265
|
themes.map((opt) => {
|
|
10341
12266
|
const Icon = opt.icon;
|
|
10342
12267
|
const active = theme === opt.value;
|
|
10343
|
-
return /* @__PURE__ */ (0,
|
|
12268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
10344
12269
|
Button_default,
|
|
10345
12270
|
{
|
|
10346
12271
|
variant: "ghost",
|
|
@@ -10356,9 +12281,9 @@ function ThemeToggleHeadless({
|
|
|
10356
12281
|
role: "menuitemradio",
|
|
10357
12282
|
"aria-checked": active,
|
|
10358
12283
|
children: [
|
|
10359
|
-
/* @__PURE__ */ (0,
|
|
10360
|
-
/* @__PURE__ */ (0,
|
|
10361
|
-
active && /* @__PURE__ */ (0,
|
|
12284
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, { className: "h-4 w-4" }),
|
|
12285
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "flex-1 text-left", children: opt.label }),
|
|
12286
|
+
active && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
10362
12287
|
]
|
|
10363
12288
|
},
|
|
10364
12289
|
opt.value
|
|
@@ -10374,10 +12299,10 @@ function ThemeToggleHeadless({
|
|
|
10374
12299
|
}
|
|
10375
12300
|
|
|
10376
12301
|
// ../../components/ui/LanguageSwitcherHeadless.tsx
|
|
10377
|
-
var
|
|
10378
|
-
var
|
|
10379
|
-
var
|
|
10380
|
-
var
|
|
12302
|
+
var import_react28 = require("react");
|
|
12303
|
+
var import_react_dom11 = require("react-dom");
|
|
12304
|
+
var import_lucide_react31 = require("lucide-react");
|
|
12305
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
10381
12306
|
function LanguageSwitcherHeadless({
|
|
10382
12307
|
locales,
|
|
10383
12308
|
currentLocale,
|
|
@@ -10385,9 +12310,9 @@ function LanguageSwitcherHeadless({
|
|
|
10385
12310
|
labels,
|
|
10386
12311
|
className
|
|
10387
12312
|
}) {
|
|
10388
|
-
const [isOpen, setIsOpen] = (0,
|
|
10389
|
-
const [dropdownPosition, setDropdownPosition] = (0,
|
|
10390
|
-
const triggerButtonRef = (0,
|
|
12313
|
+
const [isOpen, setIsOpen] = (0, import_react28.useState)(false);
|
|
12314
|
+
const [dropdownPosition, setDropdownPosition] = (0, import_react28.useState)(null);
|
|
12315
|
+
const triggerButtonRef = (0, import_react28.useRef)(null);
|
|
10391
12316
|
const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
|
|
10392
12317
|
const calculatePosition = () => {
|
|
10393
12318
|
const rect = triggerButtonRef.current?.getBoundingClientRect();
|
|
@@ -10399,8 +12324,8 @@ function LanguageSwitcherHeadless({
|
|
|
10399
12324
|
const top = rect.bottom + scrollTop + 8;
|
|
10400
12325
|
return { top, left, width };
|
|
10401
12326
|
};
|
|
10402
|
-
return /* @__PURE__ */ (0,
|
|
10403
|
-
/* @__PURE__ */ (0,
|
|
12327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("relative", className), children: [
|
|
12328
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
10404
12329
|
Button_default,
|
|
10405
12330
|
{
|
|
10406
12331
|
variant: "ghost",
|
|
@@ -10419,22 +12344,22 @@ function LanguageSwitcherHeadless({
|
|
|
10419
12344
|
"aria-expanded": isOpen,
|
|
10420
12345
|
"aria-label": labels?.heading ?? "Language",
|
|
10421
12346
|
title: labels?.heading ?? "Language",
|
|
10422
|
-
children: /* @__PURE__ */ (0,
|
|
12347
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react31.Globe, { className: "h-5 w-5" })
|
|
10423
12348
|
}
|
|
10424
12349
|
),
|
|
10425
|
-
isOpen && /* @__PURE__ */ (0,
|
|
10426
|
-
typeof window !== "undefined" && (0,
|
|
10427
|
-
typeof window !== "undefined" && dropdownPosition && (0,
|
|
10428
|
-
/* @__PURE__ */ (0,
|
|
12350
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
|
|
12351
|
+
typeof window !== "undefined" && (0, import_react_dom11.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "fixed inset-0 z-[9998]", onClick: () => setIsOpen(false) }), document.body),
|
|
12352
|
+
typeof window !== "undefined" && dropdownPosition && (0, import_react_dom11.createPortal)(
|
|
12353
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
10429
12354
|
"div",
|
|
10430
12355
|
{
|
|
10431
12356
|
className: "z-[9999] bg-card border border-border rounded-lg shadow-lg overflow-hidden",
|
|
10432
12357
|
style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
|
|
10433
12358
|
onMouseDown: (e) => e.stopPropagation(),
|
|
10434
12359
|
role: "menu",
|
|
10435
|
-
children: /* @__PURE__ */ (0,
|
|
10436
|
-
/* @__PURE__ */ (0,
|
|
10437
|
-
locales.map((language) => /* @__PURE__ */ (0,
|
|
12360
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "p-2", children: [
|
|
12361
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
|
|
12362
|
+
locales.map((language) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
10438
12363
|
Button_default,
|
|
10439
12364
|
{
|
|
10440
12365
|
variant: "ghost",
|
|
@@ -10447,9 +12372,9 @@ function LanguageSwitcherHeadless({
|
|
|
10447
12372
|
role: "menuitemradio",
|
|
10448
12373
|
"aria-checked": currentLocale === language.code,
|
|
10449
12374
|
children: [
|
|
10450
|
-
language.flag && /* @__PURE__ */ (0,
|
|
10451
|
-
/* @__PURE__ */ (0,
|
|
10452
|
-
currentLocale === language.code && /* @__PURE__ */ (0,
|
|
12375
|
+
language.flag && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-lg", children: language.flag }),
|
|
12376
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "flex-1 text-left", children: language.name }),
|
|
12377
|
+
currentLocale === language.code && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
10453
12378
|
]
|
|
10454
12379
|
},
|
|
10455
12380
|
language.code
|
|
@@ -10606,12 +12531,14 @@ function getUnderverseMessages(locale = "en") {
|
|
|
10606
12531
|
Breadcrumb,
|
|
10607
12532
|
Button,
|
|
10608
12533
|
ButtonLoading,
|
|
12534
|
+
Calendar,
|
|
10609
12535
|
Card,
|
|
10610
12536
|
Carousel,
|
|
10611
12537
|
CategoryTreeSelect,
|
|
10612
12538
|
Checkbox,
|
|
10613
12539
|
CircularProgress,
|
|
10614
12540
|
ClientOnly,
|
|
12541
|
+
ColorPicker,
|
|
10615
12542
|
Combobox,
|
|
10616
12543
|
CompactPagination,
|
|
10617
12544
|
DataTable,
|
|
@@ -10637,6 +12564,8 @@ function getUnderverseMessages(locale = "en") {
|
|
|
10637
12564
|
FormSubmitButton,
|
|
10638
12565
|
GlobalLoading,
|
|
10639
12566
|
GradientBadge,
|
|
12567
|
+
Grid,
|
|
12568
|
+
GridItem,
|
|
10640
12569
|
ImageUpload,
|
|
10641
12570
|
InlineLoading,
|
|
10642
12571
|
Input,
|
|
@@ -10644,6 +12573,8 @@ function getUnderverseMessages(locale = "en") {
|
|
|
10644
12573
|
Label,
|
|
10645
12574
|
LanguageSwitcher,
|
|
10646
12575
|
LanguageSwitcherHeadless,
|
|
12576
|
+
List,
|
|
12577
|
+
ListItem,
|
|
10647
12578
|
LoadingBar,
|
|
10648
12579
|
LoadingDots,
|
|
10649
12580
|
LoadingProgress,
|
|
@@ -10702,11 +12633,15 @@ function getUnderverseMessages(locale = "en") {
|
|
|
10702
12633
|
Textarea,
|
|
10703
12634
|
ThemeToggle,
|
|
10704
12635
|
ThemeToggleHeadless,
|
|
12636
|
+
TimePicker,
|
|
12637
|
+
Timeline,
|
|
12638
|
+
TimelineItem,
|
|
10705
12639
|
ToastProvider,
|
|
10706
12640
|
Tooltip,
|
|
10707
12641
|
VARIANT_STYLES_ALERT,
|
|
10708
12642
|
VARIANT_STYLES_BTN,
|
|
10709
12643
|
VerticalTabs,
|
|
12644
|
+
Watermark,
|
|
10710
12645
|
cn,
|
|
10711
12646
|
getUnderverseMessages,
|
|
10712
12647
|
underverseMessages,
|