@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.js
CHANGED
|
@@ -1291,7 +1291,7 @@ var Label = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
1291
1291
|
Label.displayName = "Label";
|
|
1292
1292
|
|
|
1293
1293
|
// ../../components/ui/SmartImage.tsx
|
|
1294
|
-
import
|
|
1294
|
+
import Image2 from "next/image";
|
|
1295
1295
|
import React7 from "react";
|
|
1296
1296
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1297
1297
|
var DEFAULT_FALLBACK = "/images/products/hoa-hong-do.png";
|
|
@@ -1359,7 +1359,7 @@ function SmartImage({
|
|
|
1359
1359
|
);
|
|
1360
1360
|
if (fill) {
|
|
1361
1361
|
return /* @__PURE__ */ jsx9(Wrapper, { children: /* @__PURE__ */ jsx9(
|
|
1362
|
-
|
|
1362
|
+
Image2,
|
|
1363
1363
|
{
|
|
1364
1364
|
src: resolvedSrc,
|
|
1365
1365
|
alt,
|
|
@@ -1382,7 +1382,7 @@ function SmartImage({
|
|
|
1382
1382
|
className
|
|
1383
1383
|
),
|
|
1384
1384
|
children: /* @__PURE__ */ jsx9(
|
|
1385
|
-
|
|
1385
|
+
Image2,
|
|
1386
1386
|
{
|
|
1387
1387
|
src: resolvedSrc,
|
|
1388
1388
|
alt,
|
|
@@ -5013,7 +5013,7 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
|
|
|
5013
5013
|
document.removeEventListener("keydown", handleEscape);
|
|
5014
5014
|
};
|
|
5015
5015
|
}, [isOpen]);
|
|
5016
|
-
const
|
|
5016
|
+
const isSameDay2 = (a, b) => {
|
|
5017
5017
|
if (!a || !b) return false;
|
|
5018
5018
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
5019
5019
|
};
|
|
@@ -5042,24 +5042,24 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
|
|
|
5042
5042
|
for (let i = 0; i < firstDay; i++) nodes.push(/* @__PURE__ */ jsx28("div", { className: "w-8 h-8" }, `e-${i}`));
|
|
5043
5043
|
for (let d = 1; d <= daysInMonth; d++) {
|
|
5044
5044
|
const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), d);
|
|
5045
|
-
const isSelectedStart =
|
|
5046
|
-
const isSelectedEnd =
|
|
5045
|
+
const isSelectedStart = isSameDay2(date, tempStart);
|
|
5046
|
+
const isSelectedEnd = isSameDay2(date, tempEnd);
|
|
5047
5047
|
const isHovering = hoveredDate && tempStart && !tempEnd;
|
|
5048
5048
|
let isInRange = false;
|
|
5049
5049
|
let isRangeStart = false;
|
|
5050
5050
|
let isRangeEnd = false;
|
|
5051
5051
|
if (tempStart && tempEnd) {
|
|
5052
|
-
if (
|
|
5053
|
-
if (
|
|
5052
|
+
if (isSameDay2(date, tempStart)) isRangeStart = true;
|
|
5053
|
+
if (isSameDay2(date, tempEnd)) isRangeEnd = true;
|
|
5054
5054
|
if (inRange(date, tempStart, tempEnd)) isInRange = true;
|
|
5055
5055
|
} else if (isHovering) {
|
|
5056
5056
|
if (hoveredDate > tempStart) {
|
|
5057
|
-
if (
|
|
5058
|
-
if (
|
|
5057
|
+
if (isSameDay2(date, tempStart)) isRangeStart = true;
|
|
5058
|
+
if (isSameDay2(date, hoveredDate)) isRangeEnd = true;
|
|
5059
5059
|
if (inRange(date, tempStart, hoveredDate)) isInRange = true;
|
|
5060
5060
|
} else {
|
|
5061
|
-
if (
|
|
5062
|
-
if (
|
|
5061
|
+
if (isSameDay2(date, hoveredDate)) isRangeStart = true;
|
|
5062
|
+
if (isSameDay2(date, tempStart)) isRangeEnd = true;
|
|
5063
5063
|
if (inRange(date, hoveredDate, tempStart)) isInRange = true;
|
|
5064
5064
|
}
|
|
5065
5065
|
}
|
|
@@ -5171,12 +5171,610 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
|
|
|
5171
5171
|
] });
|
|
5172
5172
|
};
|
|
5173
5173
|
|
|
5174
|
-
// ../../components/ui/
|
|
5174
|
+
// ../../components/ui/TimePicker.tsx
|
|
5175
5175
|
import * as React22 from "react";
|
|
5176
|
+
import { Clock as Clock2, X as X8 } from "lucide-react";
|
|
5177
|
+
import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5178
|
+
var pad = (n) => n.toString().padStart(2, "0");
|
|
5179
|
+
function parseTime(input, fmt = "24", includeSeconds) {
|
|
5180
|
+
if (!input) return null;
|
|
5181
|
+
const s = input.trim().toUpperCase();
|
|
5182
|
+
const ampm = s.endsWith("AM") || s.endsWith("PM");
|
|
5183
|
+
const clean = s.replace(/\s*(AM|PM)\s*$/, "");
|
|
5184
|
+
const segs = clean.split(":");
|
|
5185
|
+
const h = Number(segs[0]);
|
|
5186
|
+
const m = Number(segs[1] ?? 0);
|
|
5187
|
+
const sec = Number(segs[2] ?? 0);
|
|
5188
|
+
if (Number.isNaN(h) || Number.isNaN(m) || Number.isNaN(sec)) return null;
|
|
5189
|
+
if (fmt === "12" || ampm) {
|
|
5190
|
+
const p = s.endsWith("PM") ? "PM" : "AM";
|
|
5191
|
+
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 };
|
|
5192
|
+
}
|
|
5193
|
+
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)) };
|
|
5194
|
+
}
|
|
5195
|
+
function formatTime2({ h, m, s, p }, fmt, includeSeconds) {
|
|
5196
|
+
if (fmt === "12") {
|
|
5197
|
+
const period = p || (h >= 12 ? "PM" : "AM");
|
|
5198
|
+
const hr12 = h % 12 === 0 ? 12 : h % 12;
|
|
5199
|
+
const base2 = `${pad(hr12)}:${pad(m)}`;
|
|
5200
|
+
return includeSeconds ? `${base2}:${pad(s)} ${period}` : `${base2} ${period}`;
|
|
5201
|
+
}
|
|
5202
|
+
const base = `${pad(h)}:${pad(m)}`;
|
|
5203
|
+
return includeSeconds ? `${base}:${pad(s)}` : base;
|
|
5204
|
+
}
|
|
5205
|
+
var PRESETS = {
|
|
5206
|
+
morning: { h: 9, m: 0, s: 0 },
|
|
5207
|
+
afternoon: { h: 14, m: 0, s: 0 },
|
|
5208
|
+
evening: { h: 18, m: 0, s: 0 },
|
|
5209
|
+
night: { h: 21, m: 0, s: 0 }
|
|
5210
|
+
};
|
|
5211
|
+
function TimePicker({
|
|
5212
|
+
value,
|
|
5213
|
+
defaultValue,
|
|
5214
|
+
onChange,
|
|
5215
|
+
placeholder = "Select time",
|
|
5216
|
+
disabled = false,
|
|
5217
|
+
size = "md",
|
|
5218
|
+
label,
|
|
5219
|
+
required,
|
|
5220
|
+
format = "24",
|
|
5221
|
+
includeSeconds = false,
|
|
5222
|
+
minuteStep = 5,
|
|
5223
|
+
secondStep = 5,
|
|
5224
|
+
clearable = true,
|
|
5225
|
+
variant = "default",
|
|
5226
|
+
showNow = false,
|
|
5227
|
+
showPresets = false,
|
|
5228
|
+
allowManualInput = false,
|
|
5229
|
+
className,
|
|
5230
|
+
...rest
|
|
5231
|
+
}) {
|
|
5232
|
+
const isControlled = value !== void 0;
|
|
5233
|
+
const now = /* @__PURE__ */ new Date();
|
|
5234
|
+
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() });
|
|
5235
|
+
const [open, setOpen] = React22.useState(false);
|
|
5236
|
+
const [parts, setParts] = React22.useState(initial);
|
|
5237
|
+
const [manualInput, setManualInput] = React22.useState("");
|
|
5238
|
+
React22.useEffect(() => {
|
|
5239
|
+
if (isControlled) {
|
|
5240
|
+
const parsed = parseTime(value, format, includeSeconds);
|
|
5241
|
+
if (parsed) setParts(parsed);
|
|
5242
|
+
}
|
|
5243
|
+
}, [value, isControlled, format, includeSeconds]);
|
|
5244
|
+
const emit = (next) => {
|
|
5245
|
+
onChange?.(next ? formatTime2(next, format, includeSeconds) : void 0);
|
|
5246
|
+
};
|
|
5247
|
+
const setNow = () => {
|
|
5248
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
5249
|
+
const h = now2.getHours();
|
|
5250
|
+
const m = now2.getMinutes();
|
|
5251
|
+
const s = now2.getSeconds();
|
|
5252
|
+
let next;
|
|
5253
|
+
if (format === "12") {
|
|
5254
|
+
next = { h: h % 12 || 12, m, s, p: h >= 12 ? "PM" : "AM" };
|
|
5255
|
+
} else {
|
|
5256
|
+
next = { h, m, s };
|
|
5257
|
+
}
|
|
5258
|
+
setParts(next);
|
|
5259
|
+
emit(next);
|
|
5260
|
+
};
|
|
5261
|
+
const setPreset = (preset) => {
|
|
5262
|
+
const { h, m, s } = PRESETS[preset];
|
|
5263
|
+
let next;
|
|
5264
|
+
if (format === "12") {
|
|
5265
|
+
next = { h: h % 12 || 12, m, s, p: h >= 12 ? "PM" : "AM" };
|
|
5266
|
+
} else {
|
|
5267
|
+
next = { h, m, s };
|
|
5268
|
+
}
|
|
5269
|
+
setParts(next);
|
|
5270
|
+
emit(next);
|
|
5271
|
+
};
|
|
5272
|
+
const handleManualInput = (input) => {
|
|
5273
|
+
setManualInput(input);
|
|
5274
|
+
const parsed = parseTime(input, format, includeSeconds);
|
|
5275
|
+
if (parsed) {
|
|
5276
|
+
setParts(parsed);
|
|
5277
|
+
emit(parsed);
|
|
5278
|
+
}
|
|
5279
|
+
};
|
|
5280
|
+
const hours = format === "24" ? Array.from({ length: 24 }, (_, i) => i) : Array.from({ length: 12 }, (_, i) => i + 1);
|
|
5281
|
+
const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => Math.min(59, i * minuteStep));
|
|
5282
|
+
const seconds = Array.from({ length: Math.ceil(60 / secondStep) }, (_, i) => Math.min(59, i * secondStep));
|
|
5283
|
+
const sizeClasses2 = {
|
|
5284
|
+
sm: { label: "text-xs", height: "h-8", padding: "px-2.5 py-1.5", text: "text-xs", icon: "w-3.5 h-3.5" },
|
|
5285
|
+
md: { label: "text-sm", height: "h-10", padding: "px-3 py-2", text: "text-sm", icon: "w-4 h-4" },
|
|
5286
|
+
lg: { label: "text-base", height: "h-12", padding: "px-4 py-3", text: "text-base", icon: "w-5 h-5" }
|
|
5287
|
+
};
|
|
5288
|
+
const sz = sizeClasses2[size];
|
|
5289
|
+
const radiusClass = size === "sm" ? "rounded-md" : "rounded-lg";
|
|
5290
|
+
const display = formatTime2(parts, format, includeSeconds);
|
|
5291
|
+
const trigger = variant === "inline" ? null : /* @__PURE__ */ jsxs24(
|
|
5292
|
+
"button",
|
|
5293
|
+
{
|
|
5294
|
+
type: "button",
|
|
5295
|
+
disabled,
|
|
5296
|
+
className: cn(
|
|
5297
|
+
"flex w-full items-center justify-between border border-input bg-background",
|
|
5298
|
+
sz.height,
|
|
5299
|
+
sz.padding,
|
|
5300
|
+
sz.text,
|
|
5301
|
+
radiusClass,
|
|
5302
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
5303
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
5304
|
+
"hover:bg-accent/5 transition-colors",
|
|
5305
|
+
className
|
|
5306
|
+
),
|
|
5307
|
+
children: [
|
|
5308
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2", children: [
|
|
5309
|
+
/* @__PURE__ */ jsx29(Clock2, { className: cn(sz.icon, "text-muted-foreground") }),
|
|
5310
|
+
/* @__PURE__ */ jsx29("span", { className: cn("truncate", !value && !defaultValue && "text-muted-foreground"), children: value || defaultValue ? display : placeholder })
|
|
5311
|
+
] }),
|
|
5312
|
+
/* @__PURE__ */ jsx29("span", { className: cn("ml-2 transition-transform", open && "rotate-180"), children: /* @__PURE__ */ jsx29("svg", { className: sz.icon, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx29("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) }) })
|
|
5313
|
+
]
|
|
5314
|
+
}
|
|
5315
|
+
);
|
|
5316
|
+
const contentWidth = variant === "compact" ? 240 : variant === "inline" ? 320 : includeSeconds ? 340 : 300;
|
|
5317
|
+
const timePickerContent = /* @__PURE__ */ jsxs24("div", { className: "space-y-3", children: [
|
|
5318
|
+
allowManualInput && /* @__PURE__ */ jsx29("div", { children: /* @__PURE__ */ jsx29(
|
|
5319
|
+
Input_default,
|
|
5320
|
+
{
|
|
5321
|
+
placeholder: format === "12" ? "02:30 PM" : "14:30",
|
|
5322
|
+
value: manualInput || display,
|
|
5323
|
+
onChange: (e) => handleManualInput(e.target.value),
|
|
5324
|
+
size: "sm",
|
|
5325
|
+
variant: "outlined"
|
|
5326
|
+
}
|
|
5327
|
+
) }),
|
|
5328
|
+
showPresets && /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-2 gap-2", children: Object.keys(PRESETS).map((preset) => /* @__PURE__ */ jsx29(
|
|
5329
|
+
"button",
|
|
5330
|
+
{
|
|
5331
|
+
type: "button",
|
|
5332
|
+
className: "px-2 py-1.5 text-xs rounded-md border border-border hover:bg-accent/10 capitalize transition-colors",
|
|
5333
|
+
onClick: () => setPreset(preset),
|
|
5334
|
+
children: preset
|
|
5335
|
+
},
|
|
5336
|
+
preset
|
|
5337
|
+
)) }),
|
|
5338
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
|
|
5339
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex-1 min-w-[60px]", children: [
|
|
5340
|
+
/* @__PURE__ */ jsx29("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Hour" }),
|
|
5341
|
+
/* @__PURE__ */ jsx29("div", { className: "max-h-48 overflow-y-auto pr-1 space-y-1 scrollbar-thin", children: hours.map((h) => /* @__PURE__ */ jsx29(
|
|
5342
|
+
"button",
|
|
5343
|
+
{
|
|
5344
|
+
type: "button",
|
|
5345
|
+
className: cn(
|
|
5346
|
+
"w-full text-center px-2 py-1.5 rounded-md hover:bg-accent transition-colors text-sm",
|
|
5347
|
+
(format === "24" && parts.h === h || format === "12" && (parts.h % 12 || 12) === (h % 12 || 12)) && "bg-primary text-primary-foreground font-semibold"
|
|
5348
|
+
),
|
|
5349
|
+
onClick: () => {
|
|
5350
|
+
const nextH = format === "24" ? h : (parts.p === "PM" ? h % 12 + 12 : h % 12) % 24;
|
|
5351
|
+
const next = { ...parts, h: format === "24" ? h : nextH === 0 && parts.p === "AM" ? 0 : nextH || (parts.p === "PM" ? 12 : 0) };
|
|
5352
|
+
setParts(next);
|
|
5353
|
+
emit(next);
|
|
5354
|
+
},
|
|
5355
|
+
children: pad(h)
|
|
5356
|
+
},
|
|
5357
|
+
h
|
|
5358
|
+
)) })
|
|
5359
|
+
] }),
|
|
5360
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex-1 min-w-[60px]", children: [
|
|
5361
|
+
/* @__PURE__ */ jsx29("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Min" }),
|
|
5362
|
+
/* @__PURE__ */ jsx29("div", { className: "max-h-48 overflow-y-auto pr-1 space-y-1 scrollbar-thin", children: minutes.map((m) => /* @__PURE__ */ jsx29(
|
|
5363
|
+
"button",
|
|
5364
|
+
{
|
|
5365
|
+
type: "button",
|
|
5366
|
+
className: cn(
|
|
5367
|
+
"w-full text-center px-2 py-1.5 rounded-md hover:bg-accent transition-colors text-sm",
|
|
5368
|
+
parts.m === m && "bg-primary text-primary-foreground font-semibold"
|
|
5369
|
+
),
|
|
5370
|
+
onClick: () => {
|
|
5371
|
+
const next = { ...parts, m };
|
|
5372
|
+
setParts(next);
|
|
5373
|
+
emit(next);
|
|
5374
|
+
},
|
|
5375
|
+
children: pad(m)
|
|
5376
|
+
},
|
|
5377
|
+
m
|
|
5378
|
+
)) })
|
|
5379
|
+
] }),
|
|
5380
|
+
includeSeconds && /* @__PURE__ */ jsxs24("div", { className: "flex-1 min-w-[60px]", children: [
|
|
5381
|
+
/* @__PURE__ */ jsx29("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Sec" }),
|
|
5382
|
+
/* @__PURE__ */ jsx29("div", { className: "max-h-48 overflow-y-auto pr-1 space-y-1 scrollbar-thin", children: seconds.map((s) => /* @__PURE__ */ jsx29(
|
|
5383
|
+
"button",
|
|
5384
|
+
{
|
|
5385
|
+
type: "button",
|
|
5386
|
+
className: cn(
|
|
5387
|
+
"w-full text-center px-2 py-1.5 rounded-md hover:bg-accent transition-colors text-sm",
|
|
5388
|
+
parts.s === s && "bg-primary text-primary-foreground font-semibold"
|
|
5389
|
+
),
|
|
5390
|
+
onClick: () => {
|
|
5391
|
+
const next = { ...parts, s };
|
|
5392
|
+
setParts(next);
|
|
5393
|
+
emit(next);
|
|
5394
|
+
},
|
|
5395
|
+
children: pad(s)
|
|
5396
|
+
},
|
|
5397
|
+
s
|
|
5398
|
+
)) })
|
|
5399
|
+
] }),
|
|
5400
|
+
format === "12" && /* @__PURE__ */ jsxs24("div", { className: "w-20", children: [
|
|
5401
|
+
/* @__PURE__ */ jsx29("div", { className: "text-xs font-medium text-muted-foreground mb-1.5", children: "Period" }),
|
|
5402
|
+
/* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-1.5", children: ["AM", "PM"].map((p) => /* @__PURE__ */ jsx29(
|
|
5403
|
+
"button",
|
|
5404
|
+
{
|
|
5405
|
+
type: "button",
|
|
5406
|
+
className: cn(
|
|
5407
|
+
"px-3 py-2 rounded-md hover:bg-accent transition-colors text-sm font-medium",
|
|
5408
|
+
parts.p === p && "bg-primary text-primary-foreground"
|
|
5409
|
+
),
|
|
5410
|
+
onClick: () => {
|
|
5411
|
+
const pVal = p;
|
|
5412
|
+
let hour = parts.h;
|
|
5413
|
+
if (pVal === "AM" && hour >= 12) hour -= 12;
|
|
5414
|
+
if (pVal === "PM" && hour < 12) hour += 12;
|
|
5415
|
+
const next = { ...parts, p: pVal, h: hour };
|
|
5416
|
+
setParts(next);
|
|
5417
|
+
emit(next);
|
|
5418
|
+
},
|
|
5419
|
+
children: p
|
|
5420
|
+
},
|
|
5421
|
+
p
|
|
5422
|
+
)) })
|
|
5423
|
+
] })
|
|
5424
|
+
] }),
|
|
5425
|
+
(showNow || clearable) && /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between gap-2 pt-2 border-t border-border", children: [
|
|
5426
|
+
showNow && /* @__PURE__ */ jsxs24(
|
|
5427
|
+
"button",
|
|
5428
|
+
{
|
|
5429
|
+
type: "button",
|
|
5430
|
+
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",
|
|
5431
|
+
onClick: () => {
|
|
5432
|
+
setNow();
|
|
5433
|
+
if (variant === "compact") setOpen(false);
|
|
5434
|
+
},
|
|
5435
|
+
children: [
|
|
5436
|
+
/* @__PURE__ */ jsx29(Clock2, { className: "w-3 h-3" }),
|
|
5437
|
+
"Now"
|
|
5438
|
+
]
|
|
5439
|
+
}
|
|
5440
|
+
),
|
|
5441
|
+
/* @__PURE__ */ jsx29("div", { className: "flex-1" }),
|
|
5442
|
+
clearable && /* @__PURE__ */ jsxs24(
|
|
5443
|
+
"button",
|
|
5444
|
+
{
|
|
5445
|
+
type: "button",
|
|
5446
|
+
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",
|
|
5447
|
+
onClick: () => {
|
|
5448
|
+
setParts(initial);
|
|
5449
|
+
emit(void 0);
|
|
5450
|
+
setOpen(false);
|
|
5451
|
+
},
|
|
5452
|
+
children: [
|
|
5453
|
+
/* @__PURE__ */ jsx29(X8, { className: "w-3 h-3" }),
|
|
5454
|
+
"Clear"
|
|
5455
|
+
]
|
|
5456
|
+
}
|
|
5457
|
+
)
|
|
5458
|
+
] })
|
|
5459
|
+
] });
|
|
5460
|
+
if (variant === "inline") {
|
|
5461
|
+
return /* @__PURE__ */ jsxs24("div", { className: "w-full", ...rest, children: [
|
|
5462
|
+
label && /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ jsxs24("label", { className: cn(sz.label, "font-medium", disabled ? "text-muted-foreground" : "text-foreground"), children: [
|
|
5463
|
+
label,
|
|
5464
|
+
required && /* @__PURE__ */ jsx29("span", { className: "text-destructive ml-1", children: "*" })
|
|
5465
|
+
] }) }),
|
|
5466
|
+
/* @__PURE__ */ jsx29("div", { className: cn("p-3 rounded-lg border border-border bg-card shadow-sm", className), children: timePickerContent })
|
|
5467
|
+
] });
|
|
5468
|
+
}
|
|
5469
|
+
return /* @__PURE__ */ jsxs24("div", { className: "w-full", ...rest, children: [
|
|
5470
|
+
label && /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between mb-1.5", children: /* @__PURE__ */ jsxs24("label", { className: cn(sz.label, "font-medium", disabled ? "text-muted-foreground" : "text-foreground"), onClick: () => !disabled && setOpen(true), children: [
|
|
5471
|
+
label,
|
|
5472
|
+
required && /* @__PURE__ */ jsx29("span", { className: "text-destructive ml-1", children: "*" })
|
|
5473
|
+
] }) }),
|
|
5474
|
+
/* @__PURE__ */ jsx29(
|
|
5475
|
+
Popover,
|
|
5476
|
+
{
|
|
5477
|
+
trigger,
|
|
5478
|
+
open,
|
|
5479
|
+
onOpenChange: (o) => setOpen(o),
|
|
5480
|
+
placement: "bottom-start",
|
|
5481
|
+
matchTriggerWidth: variant === "compact",
|
|
5482
|
+
contentWidth,
|
|
5483
|
+
contentClassName: cn("p-3 rounded-lg border border-border bg-popover shadow-lg backdrop-blur-sm bg-popover/95"),
|
|
5484
|
+
children: timePickerContent
|
|
5485
|
+
}
|
|
5486
|
+
)
|
|
5487
|
+
] });
|
|
5488
|
+
}
|
|
5489
|
+
|
|
5490
|
+
// ../../components/ui/Calendar.tsx
|
|
5491
|
+
import * as React23 from "react";
|
|
5492
|
+
import { ChevronLeft as ChevronLeft3, ChevronRight as ChevronRight4 } from "lucide-react";
|
|
5493
|
+
import { Fragment as Fragment8, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5494
|
+
function startOfMonth(d) {
|
|
5495
|
+
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
5496
|
+
}
|
|
5497
|
+
function endOfMonth(d) {
|
|
5498
|
+
return new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
5499
|
+
}
|
|
5500
|
+
function addMonths(d, n) {
|
|
5501
|
+
const nd = new Date(d);
|
|
5502
|
+
nd.setMonth(d.getMonth() + n);
|
|
5503
|
+
return nd;
|
|
5504
|
+
}
|
|
5505
|
+
function isSameDay(a, b) {
|
|
5506
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
5507
|
+
}
|
|
5508
|
+
function toDate(x) {
|
|
5509
|
+
return x instanceof Date ? x : new Date(x);
|
|
5510
|
+
}
|
|
5511
|
+
function addDays(d, n) {
|
|
5512
|
+
const nd = new Date(d);
|
|
5513
|
+
nd.setDate(d.getDate() + n);
|
|
5514
|
+
return nd;
|
|
5515
|
+
}
|
|
5516
|
+
function startOfWeek(d, weekStartsOn) {
|
|
5517
|
+
const day = d.getDay();
|
|
5518
|
+
const diff = (day - weekStartsOn + 7) % 7;
|
|
5519
|
+
const s = new Date(d);
|
|
5520
|
+
s.setDate(d.getDate() - diff);
|
|
5521
|
+
return new Date(s.getFullYear(), s.getMonth(), s.getDate());
|
|
5522
|
+
}
|
|
5523
|
+
function getMonthGrid(view, weekStartsOn) {
|
|
5524
|
+
const start = startOfMonth(view);
|
|
5525
|
+
const end = endOfMonth(view);
|
|
5526
|
+
const startDay = (start.getDay() - weekStartsOn + 7) % 7;
|
|
5527
|
+
const days = [];
|
|
5528
|
+
for (let i = 0; i < startDay; i++) {
|
|
5529
|
+
const d = new Date(start);
|
|
5530
|
+
d.setDate(d.getDate() - (startDay - i));
|
|
5531
|
+
days.push(d);
|
|
5532
|
+
}
|
|
5533
|
+
for (let d = 1; d <= end.getDate(); d++) {
|
|
5534
|
+
days.push(new Date(view.getFullYear(), view.getMonth(), d));
|
|
5535
|
+
}
|
|
5536
|
+
while (days.length % 7 !== 0) {
|
|
5537
|
+
const last = days[days.length - 1];
|
|
5538
|
+
const next = new Date(last);
|
|
5539
|
+
next.setDate(last.getDate() + 1);
|
|
5540
|
+
days.push(next);
|
|
5541
|
+
}
|
|
5542
|
+
return days;
|
|
5543
|
+
}
|
|
5544
|
+
function Calendar2({
|
|
5545
|
+
month,
|
|
5546
|
+
defaultMonth,
|
|
5547
|
+
onMonthChange,
|
|
5548
|
+
value,
|
|
5549
|
+
defaultValue,
|
|
5550
|
+
onSelect,
|
|
5551
|
+
selectMode = "single",
|
|
5552
|
+
weekStartsOn = 0,
|
|
5553
|
+
showWeekdays = true,
|
|
5554
|
+
showHeader = true,
|
|
5555
|
+
size = "md",
|
|
5556
|
+
variant = "default",
|
|
5557
|
+
events = [],
|
|
5558
|
+
renderDay,
|
|
5559
|
+
labels,
|
|
5560
|
+
className,
|
|
5561
|
+
display = "month",
|
|
5562
|
+
months = 1,
|
|
5563
|
+
showToday = false,
|
|
5564
|
+
showClear = false,
|
|
5565
|
+
minDate,
|
|
5566
|
+
maxDate,
|
|
5567
|
+
disabledDates,
|
|
5568
|
+
dense = false,
|
|
5569
|
+
animate = false,
|
|
5570
|
+
showEventBadges = false,
|
|
5571
|
+
highlightWeekends = false,
|
|
5572
|
+
...rest
|
|
5573
|
+
}) {
|
|
5574
|
+
const isControlledMonth = month != null;
|
|
5575
|
+
const [view, setView] = React23.useState(() => month ?? defaultMonth ?? /* @__PURE__ */ new Date());
|
|
5576
|
+
React23.useEffect(() => {
|
|
5577
|
+
if (isControlledMonth && month) setView(month);
|
|
5578
|
+
}, [isControlledMonth, month]);
|
|
5579
|
+
const isControlledValue = value !== void 0;
|
|
5580
|
+
const [internal, setInternal] = React23.useState(defaultValue);
|
|
5581
|
+
const selected = isControlledValue ? value : internal;
|
|
5582
|
+
const goByView = (delta) => {
|
|
5583
|
+
const next = display === "week" ? addDays(view, delta * 7) : addMonths(view, delta);
|
|
5584
|
+
if (!isControlledMonth) setView(next);
|
|
5585
|
+
if (display === "month") onMonthChange?.(next);
|
|
5586
|
+
};
|
|
5587
|
+
const weekNames = labels?.weekdays ?? ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
5588
|
+
const rotate = (arr, n) => arr.slice(n).concat(arr.slice(0, n));
|
|
5589
|
+
const weekdays = rotate(weekNames, weekStartsOn);
|
|
5590
|
+
const days = getMonthGrid(view, weekStartsOn);
|
|
5591
|
+
const today = /* @__PURE__ */ new Date();
|
|
5592
|
+
const byDay = React23.useMemo(() => {
|
|
5593
|
+
const map = /* @__PURE__ */ new Map();
|
|
5594
|
+
for (const e of events) {
|
|
5595
|
+
const d = toDate(e.date);
|
|
5596
|
+
const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
5597
|
+
if (!map.has(k)) map.set(k, []);
|
|
5598
|
+
map.get(k).push(e);
|
|
5599
|
+
}
|
|
5600
|
+
return map;
|
|
5601
|
+
}, [events]);
|
|
5602
|
+
const isSelected = (d) => {
|
|
5603
|
+
if (!selected) return false;
|
|
5604
|
+
if (selectMode === "single" && selected instanceof Date) return isSameDay(selected, d);
|
|
5605
|
+
if (selectMode === "multiple" && Array.isArray(selected)) return selected.some((x) => isSameDay(x, d));
|
|
5606
|
+
if (selectMode === "range" && !Array.isArray(selected) && typeof selected === "object") {
|
|
5607
|
+
const s = selected.start;
|
|
5608
|
+
const e = selected.end;
|
|
5609
|
+
if (s && e) return d >= new Date(s.getFullYear(), s.getMonth(), s.getDate()) && d <= new Date(e.getFullYear(), e.getMonth(), e.getDate());
|
|
5610
|
+
if (s) return isSameDay(s, d);
|
|
5611
|
+
if (e) return isSameDay(e, d);
|
|
5612
|
+
}
|
|
5613
|
+
return false;
|
|
5614
|
+
};
|
|
5615
|
+
const commit = (next) => {
|
|
5616
|
+
if (!isControlledValue) setInternal(next);
|
|
5617
|
+
onSelect?.(next);
|
|
5618
|
+
};
|
|
5619
|
+
const handleClickDay = (d) => {
|
|
5620
|
+
if (selectMode === "single") {
|
|
5621
|
+
commit(d);
|
|
5622
|
+
return;
|
|
5623
|
+
}
|
|
5624
|
+
if (selectMode === "multiple") {
|
|
5625
|
+
const arr = Array.isArray(selected) ? selected : [];
|
|
5626
|
+
const exists = arr.some((x) => isSameDay(x, d));
|
|
5627
|
+
const next = exists ? arr.filter((x) => !isSameDay(x, d)) : [...arr, d];
|
|
5628
|
+
commit(next);
|
|
5629
|
+
return;
|
|
5630
|
+
}
|
|
5631
|
+
if (selectMode === "range") {
|
|
5632
|
+
const cur = !Array.isArray(selected) && typeof selected === "object" ? selected : {};
|
|
5633
|
+
const s = cur.start;
|
|
5634
|
+
const e = cur.end;
|
|
5635
|
+
if (!s || s && e) {
|
|
5636
|
+
commit({ start: d, end: void 0 });
|
|
5637
|
+
} else if (s && !e) {
|
|
5638
|
+
if (d < s) commit({ start: d, end: s });
|
|
5639
|
+
else commit({ start: s, end: d });
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
};
|
|
5643
|
+
const isDateDisabled = React23.useCallback((d) => {
|
|
5644
|
+
if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
|
|
5645
|
+
if (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
|
|
5646
|
+
if (Array.isArray(disabledDates)) {
|
|
5647
|
+
return disabledDates.some((dd) => isSameDay(dd, d));
|
|
5648
|
+
}
|
|
5649
|
+
if (typeof disabledDates === "function") {
|
|
5650
|
+
return disabledDates(d);
|
|
5651
|
+
}
|
|
5652
|
+
return false;
|
|
5653
|
+
}, [minDate, maxDate, disabledDates]);
|
|
5654
|
+
const SIZE_STYLES3 = {
|
|
5655
|
+
sm: { day: "w-8 h-8 text-[12px]", grid: dense ? "gap-0.5" : "gap-1", head: "text-[11px]", header: "text-sm" },
|
|
5656
|
+
md: { day: "w-9 h-9 text-sm", grid: dense ? "gap-1" : "gap-1.5", head: "text-xs", header: "text-sm" },
|
|
5657
|
+
lg: { day: "w-11 h-11 text-base", grid: dense ? "gap-1.5" : "gap-2", head: "text-sm", header: "text-base" },
|
|
5658
|
+
xl: { day: "w-14 h-14 text-lg", grid: dense ? "gap-2" : "gap-2.5", head: "text-base", header: "text-lg" }
|
|
5659
|
+
};
|
|
5660
|
+
const sz = SIZE_STYLES3[size];
|
|
5661
|
+
const VARIANT_STYLES2 = {
|
|
5662
|
+
default: "border border-border rounded-lg bg-card",
|
|
5663
|
+
bordered: "border-2 border-border rounded-xl bg-card shadow-sm",
|
|
5664
|
+
card: "border border-border rounded-xl bg-card shadow-lg",
|
|
5665
|
+
minimal: "bg-transparent"
|
|
5666
|
+
};
|
|
5667
|
+
const weekDays = React23.useMemo(() => {
|
|
5668
|
+
const s = startOfWeek(view, weekStartsOn);
|
|
5669
|
+
return Array.from({ length: 7 }, (_, i) => addDays(s, i));
|
|
5670
|
+
}, [view, weekStartsOn]);
|
|
5671
|
+
const renderMonth = (monthDate) => {
|
|
5672
|
+
const monthDays = getMonthGrid(monthDate, weekStartsOn);
|
|
5673
|
+
const monthLabel = labels?.month ? labels.month(monthDate) : monthDate.toLocaleDateString("en-US", { month: "long", year: "numeric" });
|
|
5674
|
+
return /* @__PURE__ */ jsxs25("div", { children: [
|
|
5675
|
+
months > 1 && /* @__PURE__ */ jsx30("div", { className: "flex items-center justify-center mb-2 text-sm font-semibold", children: monthLabel }),
|
|
5676
|
+
showWeekdays && /* @__PURE__ */ jsx30("div", { className: cn("grid grid-cols-7", sz.grid, "mb-1 text-center text-muted-foreground font-medium"), children: weekdays.map((w) => /* @__PURE__ */ jsx30("div", { className: cn(sz.head), children: w }, `${monthLabel}-${w}`)) }),
|
|
5677
|
+
/* @__PURE__ */ jsx30("div", { className: cn("grid grid-cols-7", sz.grid), children: monthDays.map((d, idx) => {
|
|
5678
|
+
const inMonth = d.getMonth() === monthDate.getMonth();
|
|
5679
|
+
const isToday2 = isSameDay(d, today);
|
|
5680
|
+
const selectedDay = isSelected(d);
|
|
5681
|
+
const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
5682
|
+
const dayEvents = byDay.get(k) || [];
|
|
5683
|
+
const disabled = isDateDisabled(d);
|
|
5684
|
+
return /* @__PURE__ */ jsxs25(
|
|
5685
|
+
"button",
|
|
5686
|
+
{
|
|
5687
|
+
onClick: () => handleClickDay(d),
|
|
5688
|
+
disabled,
|
|
5689
|
+
className: cn(
|
|
5690
|
+
"rounded-md flex items-center justify-center relative",
|
|
5691
|
+
sz.day,
|
|
5692
|
+
!inMonth && "text-muted-foreground/60",
|
|
5693
|
+
disabled && "opacity-40 cursor-not-allowed",
|
|
5694
|
+
isToday2 && !selectedDay && "ring-1 ring-primary/50",
|
|
5695
|
+
selectedDay && "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
5696
|
+
!selectedDay && "hover:bg-accent"
|
|
5697
|
+
),
|
|
5698
|
+
title: d.toDateString(),
|
|
5699
|
+
children: [
|
|
5700
|
+
d.getDate(),
|
|
5701
|
+
dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ jsx30("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, i)) })
|
|
5702
|
+
]
|
|
5703
|
+
},
|
|
5704
|
+
`${monthLabel}-${idx}`
|
|
5705
|
+
);
|
|
5706
|
+
}) })
|
|
5707
|
+
] });
|
|
5708
|
+
};
|
|
5709
|
+
const minBound = React23.useMemo(() => minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()) : void 0, [minDate]);
|
|
5710
|
+
const maxBound = React23.useMemo(() => maxDate ? new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()) : void 0, [maxDate]);
|
|
5711
|
+
const prevDisabled = React23.useMemo(() => {
|
|
5712
|
+
if (!minBound) return false;
|
|
5713
|
+
if (display === "week") {
|
|
5714
|
+
const start = startOfWeek(view, weekStartsOn);
|
|
5715
|
+
const prevEnd2 = addDays(start, -1);
|
|
5716
|
+
return prevEnd2 < minBound;
|
|
5717
|
+
}
|
|
5718
|
+
const prevEnd = endOfMonth(addMonths(view, -1));
|
|
5719
|
+
return prevEnd < minBound;
|
|
5720
|
+
}, [display, view, weekStartsOn, minBound]);
|
|
5721
|
+
const nextDisabled = React23.useMemo(() => {
|
|
5722
|
+
if (!maxBound) return false;
|
|
5723
|
+
if (display === "week") {
|
|
5724
|
+
const start = startOfWeek(view, weekStartsOn);
|
|
5725
|
+
const nextStart2 = addDays(start, 7);
|
|
5726
|
+
return nextStart2 > maxBound;
|
|
5727
|
+
}
|
|
5728
|
+
const nextStart = startOfMonth(addMonths(view, 1));
|
|
5729
|
+
return nextStart > maxBound;
|
|
5730
|
+
}, [display, view, weekStartsOn, maxBound]);
|
|
5731
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn("w-full", className), ...rest, children: [
|
|
5732
|
+
showHeader && /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between mb-2", children: [
|
|
5733
|
+
/* @__PURE__ */ jsx30("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__ */ jsx30(ChevronLeft3, { className: "h-4 w-4" }) }),
|
|
5734
|
+
/* @__PURE__ */ jsx30("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" }) }),
|
|
5735
|
+
/* @__PURE__ */ jsx30("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__ */ jsx30(ChevronRight4, { className: "h-4 w-4" }) })
|
|
5736
|
+
] }),
|
|
5737
|
+
display === "week" ? /* @__PURE__ */ jsxs25(Fragment8, { children: [
|
|
5738
|
+
showWeekdays && /* @__PURE__ */ jsx30("div", { className: cn("grid grid-cols-7", sz.grid, "mb-1 text-center text-muted-foreground font-medium"), children: weekdays.map((w) => /* @__PURE__ */ jsx30("div", { className: cn(sz.head), children: w }, `w-${w}`)) }),
|
|
5739
|
+
/* @__PURE__ */ jsx30("div", { className: cn("grid grid-cols-7", sz.grid), children: weekDays.map((d, idx) => {
|
|
5740
|
+
const inMonth = true;
|
|
5741
|
+
const isToday2 = isSameDay(d, today);
|
|
5742
|
+
const selectedDay = isSelected(d);
|
|
5743
|
+
const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
5744
|
+
const dayEvents = byDay.get(k) || [];
|
|
5745
|
+
const disabled = isDateDisabled(d);
|
|
5746
|
+
return /* @__PURE__ */ jsxs25(
|
|
5747
|
+
"button",
|
|
5748
|
+
{
|
|
5749
|
+
onClick: () => handleClickDay(d),
|
|
5750
|
+
disabled,
|
|
5751
|
+
className: cn(
|
|
5752
|
+
"rounded-md flex items-center justify-center relative",
|
|
5753
|
+
sz.day,
|
|
5754
|
+
disabled && "opacity-40 cursor-not-allowed",
|
|
5755
|
+
isToday2 && !selectedDay && "ring-1 ring-primary/50",
|
|
5756
|
+
selectedDay && "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
5757
|
+
!selectedDay && "hover:bg-accent"
|
|
5758
|
+
),
|
|
5759
|
+
title: d.toDateString(),
|
|
5760
|
+
children: [
|
|
5761
|
+
d.getDate(),
|
|
5762
|
+
dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ jsx30("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, i)) })
|
|
5763
|
+
]
|
|
5764
|
+
},
|
|
5765
|
+
`wd-${idx}`
|
|
5766
|
+
);
|
|
5767
|
+
}) })
|
|
5768
|
+
] }) : /* @__PURE__ */ jsx30("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__ */ jsx30(React23.Fragment, { children: renderMonth(addMonths(view, i)) }, `cal-month-${view.getFullYear()}-${view.getMonth()}-${i}`)) })
|
|
5769
|
+
] });
|
|
5770
|
+
}
|
|
5771
|
+
|
|
5772
|
+
// ../../components/ui/MultiCombobox.tsx
|
|
5773
|
+
import * as React24 from "react";
|
|
5176
5774
|
import { useId as useId4 } from "react";
|
|
5177
5775
|
import { createPortal as createPortal8 } from "react-dom";
|
|
5178
|
-
import { ChevronDown as ChevronDown2, Search as Search3, Check as
|
|
5179
|
-
import { jsx as
|
|
5776
|
+
import { ChevronDown as ChevronDown2, Search as Search3, Check as Check5 } from "lucide-react";
|
|
5777
|
+
import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5180
5778
|
var MultiCombobox = ({
|
|
5181
5779
|
id,
|
|
5182
5780
|
options,
|
|
@@ -5195,15 +5793,15 @@ var MultiCombobox = ({
|
|
|
5195
5793
|
required,
|
|
5196
5794
|
displayFormat = (option) => option.label
|
|
5197
5795
|
}) => {
|
|
5198
|
-
const [query, setQuery] =
|
|
5199
|
-
const [open, setOpen] =
|
|
5200
|
-
const [activeIndex, setActiveIndex] =
|
|
5201
|
-
const inputRef =
|
|
5202
|
-
const listRef =
|
|
5203
|
-
const [dropdownPosition, setDropdownPosition] =
|
|
5204
|
-
const triggerRef =
|
|
5796
|
+
const [query, setQuery] = React24.useState("");
|
|
5797
|
+
const [open, setOpen] = React24.useState(false);
|
|
5798
|
+
const [activeIndex, setActiveIndex] = React24.useState(null);
|
|
5799
|
+
const inputRef = React24.useRef(null);
|
|
5800
|
+
const listRef = React24.useRef([]);
|
|
5801
|
+
const [dropdownPosition, setDropdownPosition] = React24.useState(null);
|
|
5802
|
+
const triggerRef = React24.useRef(null);
|
|
5205
5803
|
useShadCNAnimations();
|
|
5206
|
-
const calculatePosition =
|
|
5804
|
+
const calculatePosition = React24.useCallback(() => {
|
|
5207
5805
|
if (!triggerRef.current) return null;
|
|
5208
5806
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
5209
5807
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
@@ -5214,7 +5812,7 @@ var MultiCombobox = ({
|
|
|
5214
5812
|
width: rect.width
|
|
5215
5813
|
};
|
|
5216
5814
|
}, []);
|
|
5217
|
-
|
|
5815
|
+
React24.useEffect(() => {
|
|
5218
5816
|
if (!open) return;
|
|
5219
5817
|
const handler = () => {
|
|
5220
5818
|
const pos = calculatePosition();
|
|
@@ -5227,7 +5825,7 @@ var MultiCombobox = ({
|
|
|
5227
5825
|
window.removeEventListener("scroll", handler, true);
|
|
5228
5826
|
};
|
|
5229
5827
|
}, [open, calculatePosition]);
|
|
5230
|
-
|
|
5828
|
+
React24.useEffect(() => {
|
|
5231
5829
|
if (!open) return;
|
|
5232
5830
|
const handleClickOutside = (event) => {
|
|
5233
5831
|
const target = event.target;
|
|
@@ -5250,12 +5848,12 @@ var MultiCombobox = ({
|
|
|
5250
5848
|
document.removeEventListener("keydown", handleEscape);
|
|
5251
5849
|
};
|
|
5252
5850
|
}, [open]);
|
|
5253
|
-
const normalizedOptions =
|
|
5851
|
+
const normalizedOptions = React24.useMemo(
|
|
5254
5852
|
() => options.map((o) => typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label }),
|
|
5255
5853
|
[options]
|
|
5256
5854
|
);
|
|
5257
5855
|
const enableSearch = normalizedOptions.length > 10;
|
|
5258
|
-
const filtered =
|
|
5856
|
+
const filtered = React24.useMemo(
|
|
5259
5857
|
() => enableSearch ? normalizedOptions.filter((opt) => opt.label.toLowerCase().includes(query.toLowerCase())) : normalizedOptions,
|
|
5260
5858
|
[normalizedOptions, query, enableSearch]
|
|
5261
5859
|
);
|
|
@@ -5284,7 +5882,7 @@ var MultiCombobox = ({
|
|
|
5284
5882
|
const handleClearAll = () => {
|
|
5285
5883
|
onChange([]);
|
|
5286
5884
|
};
|
|
5287
|
-
|
|
5885
|
+
React24.useEffect(() => {
|
|
5288
5886
|
if (open && enableSearch) {
|
|
5289
5887
|
setTimeout(() => {
|
|
5290
5888
|
inputRef.current?.focus();
|
|
@@ -5318,8 +5916,8 @@ var MultiCombobox = ({
|
|
|
5318
5916
|
const resolvedId = id ? String(id) : `multicombobox-${autoId}`;
|
|
5319
5917
|
const labelId = label ? `${resolvedId}-label` : void 0;
|
|
5320
5918
|
const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
|
|
5321
|
-
return /* @__PURE__ */
|
|
5322
|
-
title && /* @__PURE__ */
|
|
5919
|
+
return /* @__PURE__ */ jsxs26("div", { className: cn("w-full space-y-2 group", className), children: [
|
|
5920
|
+
title && /* @__PURE__ */ jsx31("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs26(
|
|
5323
5921
|
"label",
|
|
5324
5922
|
{
|
|
5325
5923
|
className: cn(
|
|
@@ -5329,11 +5927,11 @@ var MultiCombobox = ({
|
|
|
5329
5927
|
),
|
|
5330
5928
|
children: [
|
|
5331
5929
|
title,
|
|
5332
|
-
required && /* @__PURE__ */
|
|
5930
|
+
required && /* @__PURE__ */ jsx31("span", { className: "text-destructive ml-1", children: "*" })
|
|
5333
5931
|
]
|
|
5334
5932
|
}
|
|
5335
5933
|
) }),
|
|
5336
|
-
label && /* @__PURE__ */
|
|
5934
|
+
label && /* @__PURE__ */ jsxs26(
|
|
5337
5935
|
"label",
|
|
5338
5936
|
{
|
|
5339
5937
|
id: labelId,
|
|
@@ -5345,12 +5943,12 @@ var MultiCombobox = ({
|
|
|
5345
5943
|
),
|
|
5346
5944
|
children: [
|
|
5347
5945
|
label,
|
|
5348
|
-
required && /* @__PURE__ */
|
|
5946
|
+
required && /* @__PURE__ */ jsx31("span", { className: "text-destructive ml-1", children: "*" })
|
|
5349
5947
|
]
|
|
5350
5948
|
}
|
|
5351
5949
|
),
|
|
5352
|
-
/* @__PURE__ */
|
|
5353
|
-
/* @__PURE__ */
|
|
5950
|
+
/* @__PURE__ */ jsx31("div", { className: "relative w-full" }),
|
|
5951
|
+
/* @__PURE__ */ jsxs26(
|
|
5354
5952
|
"button",
|
|
5355
5953
|
{
|
|
5356
5954
|
ref: triggerRef,
|
|
@@ -5373,11 +5971,11 @@ var MultiCombobox = ({
|
|
|
5373
5971
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
5374
5972
|
),
|
|
5375
5973
|
children: [
|
|
5376
|
-
/* @__PURE__ */
|
|
5974
|
+
/* @__PURE__ */ jsx31("div", { className: "flex items-center gap-1 flex-wrap min-h-[1.5rem] flex-1", children: value.length > 0 ? showTags ? value.map((itemValue) => {
|
|
5377
5975
|
const option = normalizedOptions.find((o) => o.value === itemValue);
|
|
5378
|
-
return /* @__PURE__ */
|
|
5379
|
-
/* @__PURE__ */
|
|
5380
|
-
/* @__PURE__ */
|
|
5976
|
+
return /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1 bg-accent text-accent-foreground rounded px-2 py-1 text-xs", children: [
|
|
5977
|
+
/* @__PURE__ */ jsx31("span", { className: "truncate max-w-[120px]", children: option ? displayFormat(option) : itemValue }),
|
|
5978
|
+
/* @__PURE__ */ jsx31(
|
|
5381
5979
|
"span",
|
|
5382
5980
|
{
|
|
5383
5981
|
role: "button",
|
|
@@ -5400,16 +5998,16 @@ var MultiCombobox = ({
|
|
|
5400
5998
|
}
|
|
5401
5999
|
)
|
|
5402
6000
|
] }, itemValue);
|
|
5403
|
-
}) : /* @__PURE__ */
|
|
6001
|
+
}) : /* @__PURE__ */ jsxs26("span", { className: "truncate text-sm", children: [
|
|
5404
6002
|
value.length,
|
|
5405
6003
|
" selected"
|
|
5406
|
-
] }) : /* @__PURE__ */
|
|
5407
|
-
/* @__PURE__ */
|
|
6004
|
+
] }) : /* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: placeholder || "Select..." }) }),
|
|
6005
|
+
/* @__PURE__ */ jsx31(ChevronDown2, { className: cn("opacity-50 transition-transform", sizeStyles8[size].icon, open && "rotate-180") })
|
|
5408
6006
|
]
|
|
5409
6007
|
}
|
|
5410
6008
|
),
|
|
5411
6009
|
open && dropdownPosition && typeof window !== "undefined" ? createPortal8(
|
|
5412
|
-
/* @__PURE__ */
|
|
6010
|
+
/* @__PURE__ */ jsx31(
|
|
5413
6011
|
"div",
|
|
5414
6012
|
{
|
|
5415
6013
|
"data-dropdown": "multicombobox",
|
|
@@ -5426,7 +6024,7 @@ var MultiCombobox = ({
|
|
|
5426
6024
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
5427
6025
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
5428
6026
|
),
|
|
5429
|
-
children: /* @__PURE__ */
|
|
6027
|
+
children: /* @__PURE__ */ jsxs26(
|
|
5430
6028
|
"div",
|
|
5431
6029
|
{
|
|
5432
6030
|
className: cn(
|
|
@@ -5434,7 +6032,7 @@ var MultiCombobox = ({
|
|
|
5434
6032
|
"backdrop-blur-sm bg-popover/95 border-border/60"
|
|
5435
6033
|
),
|
|
5436
6034
|
children: [
|
|
5437
|
-
showClear && value.length > 0 && /* @__PURE__ */
|
|
6035
|
+
showClear && value.length > 0 && /* @__PURE__ */ jsx31("div", { className: "px-3 py-2 border-b border-border/60 flex justify-end", children: /* @__PURE__ */ jsx31(
|
|
5438
6036
|
"button",
|
|
5439
6037
|
{
|
|
5440
6038
|
type: "button",
|
|
@@ -5447,9 +6045,9 @@ var MultiCombobox = ({
|
|
|
5447
6045
|
children: "Clear all"
|
|
5448
6046
|
}
|
|
5449
6047
|
) }),
|
|
5450
|
-
enableSearch && /* @__PURE__ */
|
|
5451
|
-
/* @__PURE__ */
|
|
5452
|
-
/* @__PURE__ */
|
|
6048
|
+
enableSearch && /* @__PURE__ */ jsxs26("div", { className: "relative border-b border-border/60", children: [
|
|
6049
|
+
/* @__PURE__ */ jsx31(Search3, { className: cn("absolute left-2 top-2.5 text-muted-foreground", sizeStyles8[size].icon) }),
|
|
6050
|
+
/* @__PURE__ */ jsx31(
|
|
5453
6051
|
"input",
|
|
5454
6052
|
{
|
|
5455
6053
|
ref: inputRef,
|
|
@@ -5464,10 +6062,10 @@ var MultiCombobox = ({
|
|
|
5464
6062
|
}
|
|
5465
6063
|
)
|
|
5466
6064
|
] }),
|
|
5467
|
-
/* @__PURE__ */
|
|
6065
|
+
/* @__PURE__ */ jsx31("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) => {
|
|
5468
6066
|
const isSelected = value.includes(item.value);
|
|
5469
6067
|
const isDisabled = disabledOptions.includes(item.value);
|
|
5470
|
-
return /* @__PURE__ */
|
|
6068
|
+
return /* @__PURE__ */ jsxs26(
|
|
5471
6069
|
"li",
|
|
5472
6070
|
{
|
|
5473
6071
|
ref: (node) => {
|
|
@@ -5491,12 +6089,12 @@ var MultiCombobox = ({
|
|
|
5491
6089
|
),
|
|
5492
6090
|
children: [
|
|
5493
6091
|
item.label,
|
|
5494
|
-
isSelected && /* @__PURE__ */
|
|
6092
|
+
isSelected && /* @__PURE__ */ jsx31(Check5, { className: sizeStyles8[size].icon })
|
|
5495
6093
|
]
|
|
5496
6094
|
},
|
|
5497
6095
|
item.value
|
|
5498
6096
|
);
|
|
5499
|
-
}) : /* @__PURE__ */
|
|
6097
|
+
}) : /* @__PURE__ */ jsx31("li", { className: cn("px-3 py-2 text-muted-foreground", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: "No result." }) })
|
|
5500
6098
|
]
|
|
5501
6099
|
}
|
|
5502
6100
|
)
|
|
@@ -5508,17 +6106,17 @@ var MultiCombobox = ({
|
|
|
5508
6106
|
};
|
|
5509
6107
|
|
|
5510
6108
|
// ../../components/ui/RadioGroup.tsx
|
|
5511
|
-
import * as
|
|
5512
|
-
import { jsx as
|
|
5513
|
-
var RadioGroupContext =
|
|
6109
|
+
import * as React25 from "react";
|
|
6110
|
+
import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
6111
|
+
var RadioGroupContext = React25.createContext(void 0);
|
|
5514
6112
|
var useRadioGroup = () => {
|
|
5515
|
-
const context =
|
|
6113
|
+
const context = React25.useContext(RadioGroupContext);
|
|
5516
6114
|
if (!context) {
|
|
5517
6115
|
throw new Error("RadioGroupItem must be used within a RadioGroup");
|
|
5518
6116
|
}
|
|
5519
6117
|
return context;
|
|
5520
6118
|
};
|
|
5521
|
-
var RadioGroup =
|
|
6119
|
+
var RadioGroup = React25.forwardRef(
|
|
5522
6120
|
({
|
|
5523
6121
|
value,
|
|
5524
6122
|
defaultValue,
|
|
@@ -5534,7 +6132,7 @@ var RadioGroup = React23.forwardRef(
|
|
|
5534
6132
|
error = false,
|
|
5535
6133
|
errorMessage
|
|
5536
6134
|
}, ref) => {
|
|
5537
|
-
const [internalValue, setInternalValue] =
|
|
6135
|
+
const [internalValue, setInternalValue] = React25.useState(defaultValue || "");
|
|
5538
6136
|
const isControlled = value !== void 0;
|
|
5539
6137
|
const currentValue = isControlled ? value : internalValue;
|
|
5540
6138
|
const handleValueChange = (newValue) => {
|
|
@@ -5545,9 +6143,9 @@ var RadioGroup = React23.forwardRef(
|
|
|
5545
6143
|
onValueChange?.(newValue);
|
|
5546
6144
|
}
|
|
5547
6145
|
};
|
|
5548
|
-
const uniqueId =
|
|
6146
|
+
const uniqueId = React25.useId();
|
|
5549
6147
|
const radioName = name || `radio-group-${uniqueId}`;
|
|
5550
|
-
return /* @__PURE__ */
|
|
6148
|
+
return /* @__PURE__ */ jsx32(
|
|
5551
6149
|
RadioGroupContext.Provider,
|
|
5552
6150
|
{
|
|
5553
6151
|
value: {
|
|
@@ -5558,8 +6156,8 @@ var RadioGroup = React23.forwardRef(
|
|
|
5558
6156
|
size,
|
|
5559
6157
|
variant
|
|
5560
6158
|
},
|
|
5561
|
-
children: /* @__PURE__ */
|
|
5562
|
-
/* @__PURE__ */
|
|
6159
|
+
children: /* @__PURE__ */ jsxs27("div", { className: "space-y-2", children: [
|
|
6160
|
+
/* @__PURE__ */ jsx32(
|
|
5563
6161
|
"div",
|
|
5564
6162
|
{
|
|
5565
6163
|
ref,
|
|
@@ -5576,7 +6174,7 @@ var RadioGroup = React23.forwardRef(
|
|
|
5576
6174
|
children
|
|
5577
6175
|
}
|
|
5578
6176
|
),
|
|
5579
|
-
error && errorMessage && /* @__PURE__ */
|
|
6177
|
+
error && errorMessage && /* @__PURE__ */ jsx32("p", { className: "text-sm text-destructive mt-1", children: errorMessage })
|
|
5580
6178
|
] })
|
|
5581
6179
|
}
|
|
5582
6180
|
);
|
|
@@ -5603,7 +6201,7 @@ var sizeStyles7 = {
|
|
|
5603
6201
|
padding: "p-4"
|
|
5604
6202
|
}
|
|
5605
6203
|
};
|
|
5606
|
-
var RadioGroupItem =
|
|
6204
|
+
var RadioGroupItem = React25.forwardRef(
|
|
5607
6205
|
({ value, id, disabled, className, children, label, description, icon }, ref) => {
|
|
5608
6206
|
const {
|
|
5609
6207
|
value: selectedValue,
|
|
@@ -5618,7 +6216,7 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5618
6216
|
const Icon = icon;
|
|
5619
6217
|
const radioId = id || `radio-${value}`;
|
|
5620
6218
|
if (variant === "card") {
|
|
5621
|
-
return /* @__PURE__ */
|
|
6219
|
+
return /* @__PURE__ */ jsxs27(
|
|
5622
6220
|
"div",
|
|
5623
6221
|
{
|
|
5624
6222
|
className: cn(
|
|
@@ -5630,8 +6228,8 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5630
6228
|
className
|
|
5631
6229
|
),
|
|
5632
6230
|
children: [
|
|
5633
|
-
/* @__PURE__ */
|
|
5634
|
-
/* @__PURE__ */
|
|
6231
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-start gap-3", children: [
|
|
6232
|
+
/* @__PURE__ */ jsx32(
|
|
5635
6233
|
"button",
|
|
5636
6234
|
{
|
|
5637
6235
|
ref,
|
|
@@ -5650,22 +6248,22 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5650
6248
|
sizeStyles7[size].radio
|
|
5651
6249
|
),
|
|
5652
6250
|
onClick: () => onValueChange?.(value),
|
|
5653
|
-
children: /* @__PURE__ */
|
|
6251
|
+
children: /* @__PURE__ */ jsx32(
|
|
5654
6252
|
"span",
|
|
5655
6253
|
{
|
|
5656
6254
|
className: cn(
|
|
5657
6255
|
"flex items-center justify-center w-full h-full rounded-full transition-all duration-200",
|
|
5658
6256
|
isSelected && "bg-primary"
|
|
5659
6257
|
),
|
|
5660
|
-
children: isSelected && /* @__PURE__ */
|
|
6258
|
+
children: isSelected && /* @__PURE__ */ jsx32("span", { className: cn("bg-primary-foreground rounded-full", sizeStyles7[size].dot) })
|
|
5661
6259
|
}
|
|
5662
6260
|
)
|
|
5663
6261
|
}
|
|
5664
6262
|
),
|
|
5665
|
-
/* @__PURE__ */
|
|
5666
|
-
/* @__PURE__ */
|
|
5667
|
-
Icon && /* @__PURE__ */
|
|
5668
|
-
/* @__PURE__ */
|
|
6263
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex-1 min-w-0", children: [
|
|
6264
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2", children: [
|
|
6265
|
+
Icon && /* @__PURE__ */ jsx32(Icon, { className: "h-4 w-4 text-foreground" }),
|
|
6266
|
+
/* @__PURE__ */ jsx32(
|
|
5669
6267
|
"label",
|
|
5670
6268
|
{
|
|
5671
6269
|
htmlFor: radioId,
|
|
@@ -5677,10 +6275,10 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5677
6275
|
}
|
|
5678
6276
|
)
|
|
5679
6277
|
] }),
|
|
5680
|
-
description && /* @__PURE__ */
|
|
6278
|
+
description && /* @__PURE__ */ jsx32("p", { className: "text-muted-foreground mt-1 text-xs", children: description })
|
|
5681
6279
|
] })
|
|
5682
6280
|
] }),
|
|
5683
|
-
/* @__PURE__ */
|
|
6281
|
+
/* @__PURE__ */ jsx32(
|
|
5684
6282
|
"input",
|
|
5685
6283
|
{
|
|
5686
6284
|
type: "radio",
|
|
@@ -5698,7 +6296,7 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5698
6296
|
);
|
|
5699
6297
|
}
|
|
5700
6298
|
if (variant === "button") {
|
|
5701
|
-
return /* @__PURE__ */
|
|
6299
|
+
return /* @__PURE__ */ jsxs27(
|
|
5702
6300
|
"button",
|
|
5703
6301
|
{
|
|
5704
6302
|
ref,
|
|
@@ -5720,9 +6318,9 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5720
6318
|
),
|
|
5721
6319
|
onClick: () => onValueChange?.(value),
|
|
5722
6320
|
children: [
|
|
5723
|
-
Icon && /* @__PURE__ */
|
|
6321
|
+
Icon && /* @__PURE__ */ jsx32(Icon, { className: "h-4 w-4" }),
|
|
5724
6322
|
label || children,
|
|
5725
|
-
/* @__PURE__ */
|
|
6323
|
+
/* @__PURE__ */ jsx32(
|
|
5726
6324
|
"input",
|
|
5727
6325
|
{
|
|
5728
6326
|
type: "radio",
|
|
@@ -5739,8 +6337,8 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5739
6337
|
}
|
|
5740
6338
|
);
|
|
5741
6339
|
}
|
|
5742
|
-
return /* @__PURE__ */
|
|
5743
|
-
/* @__PURE__ */
|
|
6340
|
+
return /* @__PURE__ */ jsxs27("div", { className: cn("flex items-center gap-2", className), children: [
|
|
6341
|
+
/* @__PURE__ */ jsx32(
|
|
5744
6342
|
"button",
|
|
5745
6343
|
{
|
|
5746
6344
|
ref,
|
|
@@ -5759,19 +6357,19 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5759
6357
|
sizeStyles7[size].radio
|
|
5760
6358
|
),
|
|
5761
6359
|
onClick: () => onValueChange?.(value),
|
|
5762
|
-
children: /* @__PURE__ */
|
|
6360
|
+
children: /* @__PURE__ */ jsx32(
|
|
5763
6361
|
"span",
|
|
5764
6362
|
{
|
|
5765
6363
|
className: cn(
|
|
5766
6364
|
"flex items-center justify-center w-full h-full rounded-full transition-all duration-200",
|
|
5767
6365
|
isSelected && "bg-primary"
|
|
5768
6366
|
),
|
|
5769
|
-
children: isSelected && /* @__PURE__ */
|
|
6367
|
+
children: isSelected && /* @__PURE__ */ jsx32("span", { className: cn("bg-primary-foreground rounded-full", sizeStyles7[size].dot) })
|
|
5770
6368
|
}
|
|
5771
6369
|
)
|
|
5772
6370
|
}
|
|
5773
6371
|
),
|
|
5774
|
-
(label || children) && /* @__PURE__ */
|
|
6372
|
+
(label || children) && /* @__PURE__ */ jsxs27(
|
|
5775
6373
|
"label",
|
|
5776
6374
|
{
|
|
5777
6375
|
htmlFor: radioId,
|
|
@@ -5782,15 +6380,15 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5782
6380
|
isDisabled && "cursor-not-allowed opacity-50"
|
|
5783
6381
|
),
|
|
5784
6382
|
children: [
|
|
5785
|
-
/* @__PURE__ */
|
|
5786
|
-
Icon && /* @__PURE__ */
|
|
5787
|
-
/* @__PURE__ */
|
|
6383
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2", children: [
|
|
6384
|
+
Icon && /* @__PURE__ */ jsx32(Icon, { className: "h-4 w-4" }),
|
|
6385
|
+
/* @__PURE__ */ jsx32("span", { children: label || children })
|
|
5788
6386
|
] }),
|
|
5789
|
-
description && /* @__PURE__ */
|
|
6387
|
+
description && /* @__PURE__ */ jsx32("p", { className: "text-muted-foreground mt-0.5 text-xs", children: description })
|
|
5790
6388
|
]
|
|
5791
6389
|
}
|
|
5792
6390
|
),
|
|
5793
|
-
/* @__PURE__ */
|
|
6391
|
+
/* @__PURE__ */ jsx32(
|
|
5794
6392
|
"input",
|
|
5795
6393
|
{
|
|
5796
6394
|
type: "radio",
|
|
@@ -5809,8 +6407,8 @@ var RadioGroupItem = React23.forwardRef(
|
|
|
5809
6407
|
RadioGroupItem.displayName = "RadioGroupItem";
|
|
5810
6408
|
|
|
5811
6409
|
// ../../components/ui/Slider.tsx
|
|
5812
|
-
import * as
|
|
5813
|
-
import { jsx as
|
|
6410
|
+
import * as React26 from "react";
|
|
6411
|
+
import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5814
6412
|
var SIZE_STYLES = {
|
|
5815
6413
|
sm: {
|
|
5816
6414
|
track: "h-1",
|
|
@@ -5828,7 +6426,7 @@ var SIZE_STYLES = {
|
|
|
5828
6426
|
container: "py-3"
|
|
5829
6427
|
}
|
|
5830
6428
|
};
|
|
5831
|
-
var Slider =
|
|
6429
|
+
var Slider = React26.forwardRef(
|
|
5832
6430
|
({
|
|
5833
6431
|
className,
|
|
5834
6432
|
value,
|
|
@@ -5854,7 +6452,7 @@ var Slider = React24.forwardRef(
|
|
|
5854
6452
|
noFocus = false,
|
|
5855
6453
|
...props
|
|
5856
6454
|
}, ref) => {
|
|
5857
|
-
const [internalValue, setInternalValue] =
|
|
6455
|
+
const [internalValue, setInternalValue] = React26.useState(defaultValue);
|
|
5858
6456
|
const isControlled = value !== void 0;
|
|
5859
6457
|
const currentValue = isControlled ? value : internalValue;
|
|
5860
6458
|
const handleChange = (e) => {
|
|
@@ -5870,20 +6468,20 @@ var Slider = React24.forwardRef(
|
|
|
5870
6468
|
const displayValue = formatValue ? formatValue(currentValue) : currentValue.toString();
|
|
5871
6469
|
if (orientation === "vertical") {
|
|
5872
6470
|
}
|
|
5873
|
-
return /* @__PURE__ */
|
|
5874
|
-
(label || showValue) && /* @__PURE__ */
|
|
5875
|
-
label && /* @__PURE__ */
|
|
5876
|
-
showValue && /* @__PURE__ */
|
|
6471
|
+
return /* @__PURE__ */ jsxs28("div", { className: cn("w-full space-y-2", containerClassName), children: [
|
|
6472
|
+
(label || showValue) && /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between", children: [
|
|
6473
|
+
label && /* @__PURE__ */ jsx33("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
|
|
6474
|
+
showValue && /* @__PURE__ */ jsx33("span", { className: cn("text-xs font-mono text-muted-foreground min-w-[2rem] text-right", valueClassName), children: displayValue })
|
|
5877
6475
|
] }),
|
|
5878
|
-
/* @__PURE__ */
|
|
5879
|
-
/* @__PURE__ */
|
|
6476
|
+
/* @__PURE__ */ jsxs28("div", { className: cn("relative flex items-center", sizeStyles8.container), children: [
|
|
6477
|
+
/* @__PURE__ */ jsx33("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden", sizeStyles8.track, trackClassName), children: /* @__PURE__ */ jsx33(
|
|
5880
6478
|
"div",
|
|
5881
6479
|
{
|
|
5882
6480
|
className: "absolute left-0 top-0 h-full bg-primary rounded-full transition-all duration-150 ease-out",
|
|
5883
6481
|
style: { width: `${percentage}%` }
|
|
5884
6482
|
}
|
|
5885
6483
|
) }),
|
|
5886
|
-
/* @__PURE__ */
|
|
6484
|
+
/* @__PURE__ */ jsx33(
|
|
5887
6485
|
"input",
|
|
5888
6486
|
{
|
|
5889
6487
|
ref,
|
|
@@ -5948,8 +6546,8 @@ Slider.displayName = "Slider";
|
|
|
5948
6546
|
|
|
5949
6547
|
// ../../components/ui/OverlayControls.tsx
|
|
5950
6548
|
import { Dot, Maximize2, Pause, Play, RotateCcw, RotateCw, Volume2, VolumeX } from "lucide-react";
|
|
5951
|
-
import
|
|
5952
|
-
import { Fragment as
|
|
6549
|
+
import React27 from "react";
|
|
6550
|
+
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5953
6551
|
function OverlayControls({
|
|
5954
6552
|
mode,
|
|
5955
6553
|
value,
|
|
@@ -5979,24 +6577,24 @@ function OverlayControls({
|
|
|
5979
6577
|
}) {
|
|
5980
6578
|
const hoverClasses = showOnHover ? "opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto" : "opacity-100 pointer-events-auto";
|
|
5981
6579
|
const showControlsBar = mode === "review";
|
|
5982
|
-
const [rateOpen, setRateOpen] =
|
|
5983
|
-
const rateWrapRef =
|
|
5984
|
-
const [controlsVisible, setControlsVisible] =
|
|
5985
|
-
const hideTimerRef =
|
|
5986
|
-
const [previewData, setPreviewData] =
|
|
5987
|
-
const sliderRef =
|
|
5988
|
-
const [isDragging, setIsDragging] =
|
|
5989
|
-
const [dragValue, setDragValue] =
|
|
5990
|
-
|
|
6580
|
+
const [rateOpen, setRateOpen] = React27.useState(false);
|
|
6581
|
+
const rateWrapRef = React27.useRef(null);
|
|
6582
|
+
const [controlsVisible, setControlsVisible] = React27.useState(true);
|
|
6583
|
+
const hideTimerRef = React27.useRef(null);
|
|
6584
|
+
const [previewData, setPreviewData] = React27.useState(null);
|
|
6585
|
+
const sliderRef = React27.useRef(null);
|
|
6586
|
+
const [isDragging, setIsDragging] = React27.useState(false);
|
|
6587
|
+
const [dragValue, setDragValue] = React27.useState(value);
|
|
6588
|
+
React27.useEffect(() => {
|
|
5991
6589
|
if (!isDragging) {
|
|
5992
6590
|
setDragValue(value);
|
|
5993
6591
|
}
|
|
5994
6592
|
}, [value, isDragging]);
|
|
5995
|
-
const [keyboardFeedback, setKeyboardFeedback] =
|
|
5996
|
-
const feedbackTimerRef =
|
|
5997
|
-
const seekAccumulatorRef =
|
|
5998
|
-
const seekAccumulatorTimerRef =
|
|
5999
|
-
|
|
6593
|
+
const [keyboardFeedback, setKeyboardFeedback] = React27.useState(null);
|
|
6594
|
+
const feedbackTimerRef = React27.useRef(null);
|
|
6595
|
+
const seekAccumulatorRef = React27.useRef(0);
|
|
6596
|
+
const seekAccumulatorTimerRef = React27.useRef(null);
|
|
6597
|
+
React27.useEffect(() => {
|
|
6000
6598
|
const onDocDown = (e) => {
|
|
6001
6599
|
if (!rateOpen) return;
|
|
6002
6600
|
const wrap = rateWrapRef.current;
|
|
@@ -6007,7 +6605,7 @@ function OverlayControls({
|
|
|
6007
6605
|
document.addEventListener("mousedown", onDocDown);
|
|
6008
6606
|
return () => document.removeEventListener("mousedown", onDocDown);
|
|
6009
6607
|
}, [rateOpen]);
|
|
6010
|
-
|
|
6608
|
+
React27.useEffect(() => {
|
|
6011
6609
|
if (!autoHide || showOnHover) return;
|
|
6012
6610
|
const resetTimer = () => {
|
|
6013
6611
|
if (hideTimerRef.current) clearTimeout(hideTimerRef.current);
|
|
@@ -6045,7 +6643,7 @@ function OverlayControls({
|
|
|
6045
6643
|
seekAccumulatorRef.current = 0;
|
|
6046
6644
|
}, 1e3);
|
|
6047
6645
|
};
|
|
6048
|
-
|
|
6646
|
+
React27.useEffect(() => {
|
|
6049
6647
|
if (!enableKeyboardShortcuts) return;
|
|
6050
6648
|
const handleKeyDown = (e) => {
|
|
6051
6649
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;
|
|
@@ -6152,7 +6750,7 @@ function OverlayControls({
|
|
|
6152
6750
|
playing,
|
|
6153
6751
|
muted
|
|
6154
6752
|
]);
|
|
6155
|
-
const
|
|
6753
|
+
const formatTime3 = (sec) => {
|
|
6156
6754
|
if (!isFinite(sec) || sec < 0) return "0:00";
|
|
6157
6755
|
const h = Math.floor(sec / 3600);
|
|
6158
6756
|
const m = Math.floor(sec % 3600 / 60);
|
|
@@ -6172,41 +6770,41 @@ function OverlayControls({
|
|
|
6172
6770
|
const handleSliderMouseLeave = () => {
|
|
6173
6771
|
setPreviewData(null);
|
|
6174
6772
|
};
|
|
6175
|
-
return /* @__PURE__ */
|
|
6176
|
-
keyboardFeedback && /* @__PURE__ */
|
|
6773
|
+
return /* @__PURE__ */ jsxs29(Fragment9, { children: [
|
|
6774
|
+
keyboardFeedback && /* @__PURE__ */ jsx34(
|
|
6177
6775
|
"div",
|
|
6178
6776
|
{
|
|
6179
6777
|
className: cn(
|
|
6180
6778
|
"absolute inset-0 flex items-center pointer-events-none z-50",
|
|
6181
6779
|
keyboardFeedback.type === "seek" && (keyboardFeedback.value ?? 0) > 0 ? "justify-end pr-32" : keyboardFeedback.type === "seek" && (keyboardFeedback.value ?? 0) < 0 ? "justify-start pl-32" : "justify-center"
|
|
6182
6780
|
),
|
|
6183
|
-
children: /* @__PURE__ */
|
|
6184
|
-
keyboardFeedback.type === "play" && /* @__PURE__ */
|
|
6185
|
-
keyboardFeedback.type === "pause" && /* @__PURE__ */
|
|
6186
|
-
keyboardFeedback.type === "seek" && /* @__PURE__ */
|
|
6187
|
-
(keyboardFeedback.value ?? 0) > 0 ? /* @__PURE__ */
|
|
6188
|
-
/* @__PURE__ */
|
|
6781
|
+
children: /* @__PURE__ */ jsxs29("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: [
|
|
6782
|
+
keyboardFeedback.type === "play" && /* @__PURE__ */ jsx34(Play, { className: "w-16 h-16 text-white", fill: "white" }),
|
|
6783
|
+
keyboardFeedback.type === "pause" && /* @__PURE__ */ jsx34(Pause, { className: "w-16 h-16 text-white", fill: "white" }),
|
|
6784
|
+
keyboardFeedback.type === "seek" && /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-3", children: [
|
|
6785
|
+
(keyboardFeedback.value ?? 0) > 0 ? /* @__PURE__ */ jsx34(RotateCw, { className: "w-12 h-12 text-white" }) : /* @__PURE__ */ jsx34(RotateCcw, { className: "w-12 h-12 text-white" }),
|
|
6786
|
+
/* @__PURE__ */ jsxs29("span", { className: "text-3xl font-bold text-white", children: [
|
|
6189
6787
|
keyboardFeedback.value && keyboardFeedback.value > 0 ? "+" : "",
|
|
6190
6788
|
keyboardFeedback.value,
|
|
6191
6789
|
"s"
|
|
6192
6790
|
] })
|
|
6193
6791
|
] }),
|
|
6194
|
-
keyboardFeedback.type === "volume" && /* @__PURE__ */
|
|
6195
|
-
/* @__PURE__ */
|
|
6196
|
-
/* @__PURE__ */
|
|
6197
|
-
/* @__PURE__ */
|
|
6792
|
+
keyboardFeedback.type === "volume" && /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-3", children: [
|
|
6793
|
+
/* @__PURE__ */ jsx34(Volume2, { className: "w-12 h-12 text-white" }),
|
|
6794
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-1.5", children: [
|
|
6795
|
+
/* @__PURE__ */ jsxs29("span", { className: "text-2xl font-bold text-white", children: [
|
|
6198
6796
|
keyboardFeedback.value,
|
|
6199
6797
|
"%"
|
|
6200
6798
|
] }),
|
|
6201
|
-
/* @__PURE__ */
|
|
6799
|
+
/* @__PURE__ */ jsx34("div", { className: "w-32 h-1.5 bg-white/30 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx34("div", { className: "h-full bg-white rounded-full transition-all", style: { width: `${keyboardFeedback.value}%` } }) })
|
|
6202
6800
|
] })
|
|
6203
6801
|
] }),
|
|
6204
|
-
keyboardFeedback.type === "mute" && /* @__PURE__ */
|
|
6205
|
-
keyboardFeedback.type === "unmute" && /* @__PURE__ */
|
|
6802
|
+
keyboardFeedback.type === "mute" && /* @__PURE__ */ jsx34(VolumeX, { className: "w-16 h-16 text-white" }),
|
|
6803
|
+
keyboardFeedback.type === "unmute" && /* @__PURE__ */ jsx34(Volume2, { className: "w-16 h-16 text-white" })
|
|
6206
6804
|
] })
|
|
6207
6805
|
}
|
|
6208
6806
|
),
|
|
6209
|
-
/* @__PURE__ */
|
|
6807
|
+
/* @__PURE__ */ jsx34(
|
|
6210
6808
|
"div",
|
|
6211
6809
|
{
|
|
6212
6810
|
className: cn(
|
|
@@ -6215,9 +6813,9 @@ function OverlayControls({
|
|
|
6215
6813
|
autoHide && !controlsVisible && "opacity-0 pointer-events-none",
|
|
6216
6814
|
className
|
|
6217
6815
|
),
|
|
6218
|
-
children: /* @__PURE__ */
|
|
6219
|
-
/* @__PURE__ */
|
|
6220
|
-
/* @__PURE__ */
|
|
6816
|
+
children: /* @__PURE__ */ jsxs29("div", { className: "px-4", children: [
|
|
6817
|
+
/* @__PURE__ */ jsxs29("div", { ref: sliderRef, onMouseMove: handleSliderMouseMove, onMouseLeave: handleSliderMouseLeave, className: "relative", children: [
|
|
6818
|
+
/* @__PURE__ */ jsx34(
|
|
6221
6819
|
Slider,
|
|
6222
6820
|
{
|
|
6223
6821
|
min: 0,
|
|
@@ -6242,14 +6840,14 @@ function OverlayControls({
|
|
|
6242
6840
|
noFocus: true
|
|
6243
6841
|
}
|
|
6244
6842
|
),
|
|
6245
|
-
previewData && /* @__PURE__ */
|
|
6246
|
-
/* @__PURE__ */
|
|
6247
|
-
/* @__PURE__ */
|
|
6248
|
-
] }) : /* @__PURE__ */
|
|
6843
|
+
previewData && /* @__PURE__ */ jsx34("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__ */ jsxs29("div", { className: "bg-background/95 backdrop-blur rounded-md border border-border shadow-lg overflow-hidden", children: [
|
|
6844
|
+
/* @__PURE__ */ jsx34("img", { src: previewData.url, alt: "Preview", className: "w-40 h-24 object-cover" }),
|
|
6845
|
+
/* @__PURE__ */ jsx34("div", { className: "px-2 py-1 text-xs font-mono text-center bg-background/80", children: formatTime3(previewData.time) })
|
|
6846
|
+
] }) : /* @__PURE__ */ jsx34("div", { className: "px-3 py-1.5 rounded-md bg-background/90 backdrop-blur border border-border shadow-lg", children: /* @__PURE__ */ jsx34("div", { className: "text-xs font-mono text-center", children: formatTime3(previewData.time) }) }) })
|
|
6249
6847
|
] }),
|
|
6250
|
-
showControlsBar && /* @__PURE__ */
|
|
6251
|
-
/* @__PURE__ */
|
|
6252
|
-
/* @__PURE__ */
|
|
6848
|
+
showControlsBar && /* @__PURE__ */ jsxs29("div", { className: "mt-2 flex items-center justify-between gap-2", children: [
|
|
6849
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2", children: [
|
|
6850
|
+
/* @__PURE__ */ jsx34(
|
|
6253
6851
|
Button_default,
|
|
6254
6852
|
{
|
|
6255
6853
|
variant: "ghost",
|
|
@@ -6257,10 +6855,10 @@ function OverlayControls({
|
|
|
6257
6855
|
onClick: onTogglePlay,
|
|
6258
6856
|
title: playing ? "T\u1EA1m d\u1EEBng" : "Ph\xE1t",
|
|
6259
6857
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6260
|
-
children: playing ? /* @__PURE__ */
|
|
6858
|
+
children: playing ? /* @__PURE__ */ jsx34(Pause, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx34(Play, { className: "w-4 h-4" })
|
|
6261
6859
|
}
|
|
6262
6860
|
),
|
|
6263
|
-
onSkip && /* @__PURE__ */
|
|
6861
|
+
onSkip && /* @__PURE__ */ jsx34(
|
|
6264
6862
|
Button_default,
|
|
6265
6863
|
{
|
|
6266
6864
|
variant: "ghost",
|
|
@@ -6268,10 +6866,10 @@ function OverlayControls({
|
|
|
6268
6866
|
onClick: () => onSkip(-skipSeconds),
|
|
6269
6867
|
title: `L\xF9i ${skipSeconds}s`,
|
|
6270
6868
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6271
|
-
children: /* @__PURE__ */
|
|
6869
|
+
children: /* @__PURE__ */ jsx34(RotateCcw, { className: "w-4 h-4" })
|
|
6272
6870
|
}
|
|
6273
6871
|
),
|
|
6274
|
-
onSkip && /* @__PURE__ */
|
|
6872
|
+
onSkip && /* @__PURE__ */ jsx34(
|
|
6275
6873
|
Button_default,
|
|
6276
6874
|
{
|
|
6277
6875
|
variant: "ghost",
|
|
@@ -6279,16 +6877,16 @@ function OverlayControls({
|
|
|
6279
6877
|
onClick: () => onSkip(skipSeconds),
|
|
6280
6878
|
title: `Tua ${skipSeconds}s`,
|
|
6281
6879
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6282
|
-
children: /* @__PURE__ */
|
|
6880
|
+
children: /* @__PURE__ */ jsx34(RotateCw, { className: "w-4 h-4" })
|
|
6283
6881
|
}
|
|
6284
6882
|
),
|
|
6285
|
-
(showTime ?? true) && /* @__PURE__ */
|
|
6286
|
-
|
|
6883
|
+
(showTime ?? true) && /* @__PURE__ */ jsxs29("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: [
|
|
6884
|
+
formatTime3(dragValue),
|
|
6287
6885
|
" / ",
|
|
6288
|
-
|
|
6886
|
+
formatTime3(max)
|
|
6289
6887
|
] }),
|
|
6290
|
-
/* @__PURE__ */
|
|
6291
|
-
/* @__PURE__ */
|
|
6888
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2", children: [
|
|
6889
|
+
/* @__PURE__ */ jsx34(
|
|
6292
6890
|
Button_default,
|
|
6293
6891
|
{
|
|
6294
6892
|
variant: "ghost",
|
|
@@ -6296,10 +6894,10 @@ function OverlayControls({
|
|
|
6296
6894
|
onClick: onToggleMute,
|
|
6297
6895
|
title: muted ? "B\u1EADt ti\u1EBFng" : "T\u1EAFt ti\u1EBFng",
|
|
6298
6896
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6299
|
-
children: muted || (volume ?? 1) === 0 ? /* @__PURE__ */
|
|
6897
|
+
children: muted || (volume ?? 1) === 0 ? /* @__PURE__ */ jsx34(VolumeX, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx34(Volume2, { className: "w-4 h-4" })
|
|
6300
6898
|
}
|
|
6301
6899
|
),
|
|
6302
|
-
/* @__PURE__ */
|
|
6900
|
+
/* @__PURE__ */ jsx34("div", { className: "w-24", children: /* @__PURE__ */ jsx34(
|
|
6303
6901
|
Slider,
|
|
6304
6902
|
{
|
|
6305
6903
|
min: 0,
|
|
@@ -6314,8 +6912,8 @@ function OverlayControls({
|
|
|
6314
6912
|
) })
|
|
6315
6913
|
] })
|
|
6316
6914
|
] }),
|
|
6317
|
-
/* @__PURE__ */
|
|
6318
|
-
onGoLive && /* @__PURE__ */
|
|
6915
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-2 relative", children: [
|
|
6916
|
+
onGoLive && /* @__PURE__ */ jsxs29(
|
|
6319
6917
|
Button_default,
|
|
6320
6918
|
{
|
|
6321
6919
|
variant: "ghost",
|
|
@@ -6324,13 +6922,13 @@ function OverlayControls({
|
|
|
6324
6922
|
title: "Tr\u1EF1c ti\u1EBFp (v\u1EC1 Live)",
|
|
6325
6923
|
className: "bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6326
6924
|
children: [
|
|
6327
|
-
/* @__PURE__ */
|
|
6925
|
+
/* @__PURE__ */ jsx34(Dot, { className: "w-10 h-10 text-destructive" }),
|
|
6328
6926
|
"Tr\u1EF1c ti\u1EBFp"
|
|
6329
6927
|
]
|
|
6330
6928
|
}
|
|
6331
6929
|
),
|
|
6332
|
-
onChangeRate && /* @__PURE__ */
|
|
6333
|
-
/* @__PURE__ */
|
|
6930
|
+
onChangeRate && /* @__PURE__ */ jsxs29("div", { className: "relative", ref: rateWrapRef, children: [
|
|
6931
|
+
/* @__PURE__ */ jsxs29(
|
|
6334
6932
|
Button_default,
|
|
6335
6933
|
{
|
|
6336
6934
|
variant: "ghost",
|
|
@@ -6344,7 +6942,7 @@ function OverlayControls({
|
|
|
6344
6942
|
]
|
|
6345
6943
|
}
|
|
6346
6944
|
),
|
|
6347
|
-
rateOpen && /* @__PURE__ */
|
|
6945
|
+
rateOpen && /* @__PURE__ */ jsx34("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__ */ jsxs29(
|
|
6348
6946
|
"button",
|
|
6349
6947
|
{
|
|
6350
6948
|
onClick: () => {
|
|
@@ -6360,7 +6958,7 @@ function OverlayControls({
|
|
|
6360
6958
|
r
|
|
6361
6959
|
)) })
|
|
6362
6960
|
] }),
|
|
6363
|
-
onToggleFullscreen && /* @__PURE__ */
|
|
6961
|
+
onToggleFullscreen && /* @__PURE__ */ jsx34(
|
|
6364
6962
|
Button_default,
|
|
6365
6963
|
{
|
|
6366
6964
|
variant: "ghost",
|
|
@@ -6368,7 +6966,7 @@ function OverlayControls({
|
|
|
6368
6966
|
onClick: onToggleFullscreen,
|
|
6369
6967
|
title: "To\xE0n m\xE0n h\xECnh",
|
|
6370
6968
|
className: "px-3 bg-background/60 hover:bg-background/80 border-transparent shadow-sm outline-none focus:outline-none focus:ring-0",
|
|
6371
|
-
children: /* @__PURE__ */
|
|
6969
|
+
children: /* @__PURE__ */ jsx34(Maximize2, { className: "w-4 h-4" })
|
|
6372
6970
|
}
|
|
6373
6971
|
)
|
|
6374
6972
|
] })
|
|
@@ -6380,12 +6978,12 @@ function OverlayControls({
|
|
|
6380
6978
|
}
|
|
6381
6979
|
|
|
6382
6980
|
// ../../components/ui/CategoryTreeSelect.tsx
|
|
6383
|
-
import { useState as
|
|
6384
|
-
import { ChevronRight as
|
|
6385
|
-
import { Fragment as
|
|
6981
|
+
import { useState as useState24 } from "react";
|
|
6982
|
+
import { ChevronRight as ChevronRight5, ChevronDown as ChevronDown3, Check as Check6 } from "lucide-react";
|
|
6983
|
+
import { Fragment as Fragment10, jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6386
6984
|
function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1ECDn danh m\u1EE5c", disabled }) {
|
|
6387
|
-
const [isOpen, setIsOpen] =
|
|
6388
|
-
const [expandedNodes, setExpandedNodes] =
|
|
6985
|
+
const [isOpen, setIsOpen] = useState24(false);
|
|
6986
|
+
const [expandedNodes, setExpandedNodes] = useState24(/* @__PURE__ */ new Set());
|
|
6389
6987
|
const parentCategories = categories.filter((c) => !c.parent_id);
|
|
6390
6988
|
const childrenMap = /* @__PURE__ */ new Map();
|
|
6391
6989
|
categories.forEach((cat) => {
|
|
@@ -6424,8 +7022,8 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6424
7022
|
const hasChildren = children.length > 0;
|
|
6425
7023
|
const isExpanded = expandedNodes.has(category.id);
|
|
6426
7024
|
const isSelected = value.includes(category.id);
|
|
6427
|
-
return /* @__PURE__ */
|
|
6428
|
-
/* @__PURE__ */
|
|
7025
|
+
return /* @__PURE__ */ jsxs30("div", { children: [
|
|
7026
|
+
/* @__PURE__ */ jsxs30(
|
|
6429
7027
|
"div",
|
|
6430
7028
|
{
|
|
6431
7029
|
className: cn(
|
|
@@ -6436,14 +7034,14 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6436
7034
|
),
|
|
6437
7035
|
style: { paddingLeft: `${level * 1.5 + 0.75}rem` },
|
|
6438
7036
|
children: [
|
|
6439
|
-
isSelected && /* @__PURE__ */
|
|
7037
|
+
isSelected && /* @__PURE__ */ jsx35(
|
|
6440
7038
|
"span",
|
|
6441
7039
|
{
|
|
6442
7040
|
"aria-hidden": true,
|
|
6443
7041
|
className: "absolute left-0 top-0 bottom-0 w-1 bg-primary"
|
|
6444
7042
|
}
|
|
6445
7043
|
),
|
|
6446
|
-
hasChildren ? /* @__PURE__ */
|
|
7044
|
+
hasChildren ? /* @__PURE__ */ jsx35(
|
|
6447
7045
|
"button",
|
|
6448
7046
|
{
|
|
6449
7047
|
type: "button",
|
|
@@ -6452,39 +7050,39 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6452
7050
|
toggleExpand(category.id);
|
|
6453
7051
|
},
|
|
6454
7052
|
className: "p-0.5 hover:bg-accent rounded",
|
|
6455
|
-
children: isExpanded ? /* @__PURE__ */
|
|
7053
|
+
children: isExpanded ? /* @__PURE__ */ jsx35(ChevronDown3, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx35(ChevronRight5, { className: "w-4 h-4" })
|
|
6456
7054
|
}
|
|
6457
|
-
) : /* @__PURE__ */
|
|
6458
|
-
/* @__PURE__ */
|
|
7055
|
+
) : /* @__PURE__ */ jsx35("span", { className: "w-5" }),
|
|
7056
|
+
/* @__PURE__ */ jsxs30(
|
|
6459
7057
|
"div",
|
|
6460
7058
|
{
|
|
6461
7059
|
onClick: () => handleSelect(category.id, category),
|
|
6462
7060
|
className: "flex items-center gap-2 flex-1",
|
|
6463
7061
|
children: [
|
|
6464
|
-
/* @__PURE__ */
|
|
7062
|
+
/* @__PURE__ */ jsx35(
|
|
6465
7063
|
"div",
|
|
6466
7064
|
{
|
|
6467
7065
|
className: cn(
|
|
6468
7066
|
"w-4 h-4 border-2 rounded flex items-center justify-center transition-colors",
|
|
6469
7067
|
isSelected ? "bg-primary border-primary" : "border-muted-foreground/30"
|
|
6470
7068
|
),
|
|
6471
|
-
children: isSelected && /* @__PURE__ */
|
|
7069
|
+
children: isSelected && /* @__PURE__ */ jsx35(Check6, { className: "w-3 h-3 text-primary-foreground" })
|
|
6472
7070
|
}
|
|
6473
7071
|
),
|
|
6474
|
-
/* @__PURE__ */
|
|
7072
|
+
/* @__PURE__ */ jsx35("span", { className: cn("text-sm", isSelected && "font-medium text-primary"), children: category.name })
|
|
6475
7073
|
]
|
|
6476
7074
|
}
|
|
6477
7075
|
)
|
|
6478
7076
|
]
|
|
6479
7077
|
}
|
|
6480
7078
|
),
|
|
6481
|
-
hasChildren && isExpanded && /* @__PURE__ */
|
|
7079
|
+
hasChildren && isExpanded && /* @__PURE__ */ jsx35("div", { children: children.map((child) => renderCategory(child, level + 1)) })
|
|
6482
7080
|
] }, category.id);
|
|
6483
7081
|
};
|
|
6484
7082
|
const selectedCount = value.length;
|
|
6485
7083
|
const displayText = selectedCount > 0 ? `\u0110\xE3 ch\u1ECDn ${selectedCount} danh m\u1EE5c` : placeholder;
|
|
6486
|
-
return /* @__PURE__ */
|
|
6487
|
-
/* @__PURE__ */
|
|
7084
|
+
return /* @__PURE__ */ jsxs30("div", { className: "relative", children: [
|
|
7085
|
+
/* @__PURE__ */ jsxs30(
|
|
6488
7086
|
"button",
|
|
6489
7087
|
{
|
|
6490
7088
|
type: "button",
|
|
@@ -6500,14 +7098,14 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6500
7098
|
isOpen && "border-primary"
|
|
6501
7099
|
),
|
|
6502
7100
|
children: [
|
|
6503
|
-
/* @__PURE__ */
|
|
6504
|
-
/* @__PURE__ */
|
|
7101
|
+
/* @__PURE__ */ jsx35("span", { className: cn("text-sm", selectedCount === 0 && "text-muted-foreground"), children: displayText }),
|
|
7102
|
+
/* @__PURE__ */ jsx35(ChevronDown3, { className: cn("w-4 h-4 transition-transform", isOpen && "transform rotate-180") })
|
|
6505
7103
|
]
|
|
6506
7104
|
}
|
|
6507
7105
|
),
|
|
6508
|
-
isOpen && !disabled && /* @__PURE__ */
|
|
6509
|
-
/* @__PURE__ */
|
|
6510
|
-
/* @__PURE__ */
|
|
7106
|
+
isOpen && !disabled && /* @__PURE__ */ jsxs30(Fragment10, { children: [
|
|
7107
|
+
/* @__PURE__ */ jsx35("div", { className: "fixed inset-0 z-10", onClick: () => setIsOpen(false) }),
|
|
7108
|
+
/* @__PURE__ */ jsx35(
|
|
6511
7109
|
"div",
|
|
6512
7110
|
{
|
|
6513
7111
|
className: cn(
|
|
@@ -6515,7 +7113,7 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6515
7113
|
"rounded-md border bg-popover text-popover-foreground shadow-md",
|
|
6516
7114
|
"backdrop-blur-sm bg-popover/95 border-border/60"
|
|
6517
7115
|
),
|
|
6518
|
-
children: /* @__PURE__ */
|
|
7116
|
+
children: /* @__PURE__ */ jsx35("div", { className: "p-1", children: parentCategories.length === 0 ? /* @__PURE__ */ jsx35("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)) })
|
|
6519
7117
|
}
|
|
6520
7118
|
)
|
|
6521
7119
|
] })
|
|
@@ -6523,10 +7121,10 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
6523
7121
|
}
|
|
6524
7122
|
|
|
6525
7123
|
// ../../components/ui/ImageUpload.tsx
|
|
6526
|
-
import { useState as
|
|
6527
|
-
import { Upload, X as
|
|
7124
|
+
import { useState as useState25, useRef as useRef9, useCallback as useCallback8 } from "react";
|
|
7125
|
+
import { Upload, X as X9, Image as ImageIcon, Loader2 as Loader22, Check as Check7 } from "lucide-react";
|
|
6528
7126
|
import { useTranslations as useTranslations6 } from "next-intl";
|
|
6529
|
-
import { jsx as
|
|
7127
|
+
import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
6530
7128
|
function ImageUpload({
|
|
6531
7129
|
onUpload,
|
|
6532
7130
|
onRemove,
|
|
@@ -6542,9 +7140,9 @@ function ImageUpload({
|
|
|
6542
7140
|
browseText,
|
|
6543
7141
|
supportedFormatsText
|
|
6544
7142
|
}) {
|
|
6545
|
-
const [isDragging, setIsDragging] =
|
|
6546
|
-
const [uploading, setUploading] =
|
|
6547
|
-
const [uploadedImages, setUploadedImages] =
|
|
7143
|
+
const [isDragging, setIsDragging] = useState25(false);
|
|
7144
|
+
const [uploading, setUploading] = useState25(false);
|
|
7145
|
+
const [uploadedImages, setUploadedImages] = useState25([]);
|
|
6548
7146
|
const fileInputRef = useRef9(null);
|
|
6549
7147
|
const { addToast } = useToast();
|
|
6550
7148
|
const t = useTranslations6("OCR.imageUpload");
|
|
@@ -6553,17 +7151,17 @@ function ImageUpload({
|
|
|
6553
7151
|
md: "w-24 h-24",
|
|
6554
7152
|
lg: "w-32 h-32"
|
|
6555
7153
|
};
|
|
6556
|
-
const handleDragOver =
|
|
7154
|
+
const handleDragOver = useCallback8((e) => {
|
|
6557
7155
|
e.preventDefault();
|
|
6558
7156
|
if (!disabled) {
|
|
6559
7157
|
setIsDragging(true);
|
|
6560
7158
|
}
|
|
6561
7159
|
}, [disabled]);
|
|
6562
|
-
const handleDragLeave =
|
|
7160
|
+
const handleDragLeave = useCallback8((e) => {
|
|
6563
7161
|
e.preventDefault();
|
|
6564
7162
|
setIsDragging(false);
|
|
6565
7163
|
}, []);
|
|
6566
|
-
const handleFiles =
|
|
7164
|
+
const handleFiles = useCallback8(async (files) => {
|
|
6567
7165
|
if (files.length === 0) return;
|
|
6568
7166
|
const validFiles = files.filter((file) => {
|
|
6569
7167
|
if (file.size > maxSize * 1024 * 1024) {
|
|
@@ -6627,14 +7225,14 @@ function ImageUpload({
|
|
|
6627
7225
|
setUploading(false);
|
|
6628
7226
|
}
|
|
6629
7227
|
}, [maxSize, addToast, onUpload]);
|
|
6630
|
-
const handleDrop =
|
|
7228
|
+
const handleDrop = useCallback8((e) => {
|
|
6631
7229
|
e.preventDefault();
|
|
6632
7230
|
setIsDragging(false);
|
|
6633
7231
|
if (disabled) return;
|
|
6634
7232
|
const files = Array.from(e.dataTransfer.files);
|
|
6635
7233
|
handleFiles(files);
|
|
6636
7234
|
}, [disabled, handleFiles]);
|
|
6637
|
-
const handleFileSelect =
|
|
7235
|
+
const handleFileSelect = useCallback8((e) => {
|
|
6638
7236
|
const files = Array.from(e.target.files || []);
|
|
6639
7237
|
handleFiles(files);
|
|
6640
7238
|
if (fileInputRef.current) {
|
|
@@ -6648,8 +7246,8 @@ function ImageUpload({
|
|
|
6648
7246
|
const handleBrowseClick = () => {
|
|
6649
7247
|
fileInputRef.current?.click();
|
|
6650
7248
|
};
|
|
6651
|
-
return /* @__PURE__ */
|
|
6652
|
-
/* @__PURE__ */
|
|
7249
|
+
return /* @__PURE__ */ jsxs31("div", { className: cn("space-y-4", className), children: [
|
|
7250
|
+
/* @__PURE__ */ jsxs31(
|
|
6653
7251
|
"div",
|
|
6654
7252
|
{
|
|
6655
7253
|
className: cn(
|
|
@@ -6662,15 +7260,15 @@ function ImageUpload({
|
|
|
6662
7260
|
onDragLeave: handleDragLeave,
|
|
6663
7261
|
onDrop: handleDrop,
|
|
6664
7262
|
children: [
|
|
6665
|
-
uploading && /* @__PURE__ */
|
|
6666
|
-
/* @__PURE__ */
|
|
6667
|
-
/* @__PURE__ */
|
|
7263
|
+
uploading && /* @__PURE__ */ jsx36("div", { className: "absolute inset-0 bg-background/80 flex items-center justify-center rounded-lg", children: /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-3", children: [
|
|
7264
|
+
/* @__PURE__ */ jsx36(Loader22, { className: "w-6 h-6 animate-spin text-primary" }),
|
|
7265
|
+
/* @__PURE__ */ jsx36("span", { className: "text-sm font-medium", children: "Uploading..." })
|
|
6668
7266
|
] }) }),
|
|
6669
|
-
/* @__PURE__ */
|
|
6670
|
-
/* @__PURE__ */
|
|
6671
|
-
/* @__PURE__ */
|
|
6672
|
-
/* @__PURE__ */
|
|
6673
|
-
/* @__PURE__ */
|
|
7267
|
+
/* @__PURE__ */ jsxs31("div", { className: "space-y-4", children: [
|
|
7268
|
+
/* @__PURE__ */ jsx36("div", { className: "mx-auto w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx36(Upload, { className: "w-6 h-6 text-primary" }) }),
|
|
7269
|
+
/* @__PURE__ */ jsxs31("div", { className: "space-y-2", children: [
|
|
7270
|
+
/* @__PURE__ */ jsx36("p", { className: "text-muted-foreground", children: dragDropText || t("dragDropText") }),
|
|
7271
|
+
/* @__PURE__ */ jsx36(
|
|
6674
7272
|
Button_default,
|
|
6675
7273
|
{
|
|
6676
7274
|
type: "button",
|
|
@@ -6682,9 +7280,9 @@ function ImageUpload({
|
|
|
6682
7280
|
}
|
|
6683
7281
|
)
|
|
6684
7282
|
] }),
|
|
6685
|
-
/* @__PURE__ */
|
|
7283
|
+
/* @__PURE__ */ jsx36("p", { className: "text-xs text-muted-foreground", children: supportedFormatsText || t("supportedFormats") })
|
|
6686
7284
|
] }),
|
|
6687
|
-
/* @__PURE__ */
|
|
7285
|
+
/* @__PURE__ */ jsx36(
|
|
6688
7286
|
"input",
|
|
6689
7287
|
{
|
|
6690
7288
|
ref: fileInputRef,
|
|
@@ -6699,25 +7297,25 @@ function ImageUpload({
|
|
|
6699
7297
|
]
|
|
6700
7298
|
}
|
|
6701
7299
|
),
|
|
6702
|
-
showPreview && uploadedImages.length > 0 && /* @__PURE__ */
|
|
6703
|
-
/* @__PURE__ */
|
|
6704
|
-
/* @__PURE__ */
|
|
7300
|
+
showPreview && uploadedImages.length > 0 && /* @__PURE__ */ jsxs31("div", { className: "space-y-3", children: [
|
|
7301
|
+
/* @__PURE__ */ jsx36("h4", { className: "text-sm font-medium", children: "Uploaded Images" }),
|
|
7302
|
+
/* @__PURE__ */ jsx36("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4", children: uploadedImages.map((image) => /* @__PURE__ */ jsxs31(
|
|
6705
7303
|
"div",
|
|
6706
7304
|
{
|
|
6707
7305
|
className: "relative group bg-card border border-border rounded-lg p-3",
|
|
6708
7306
|
children: [
|
|
6709
|
-
/* @__PURE__ */
|
|
7307
|
+
/* @__PURE__ */ jsx36(
|
|
6710
7308
|
Button_default,
|
|
6711
7309
|
{
|
|
6712
7310
|
variant: "danger",
|
|
6713
7311
|
size: "icon",
|
|
6714
7312
|
className: "absolute -top-2 -right-2 w-6 h-6 opacity-0 group-hover:opacity-100 transition-opacity z-10",
|
|
6715
7313
|
onClick: () => handleRemoveImage(image.id),
|
|
6716
|
-
children: /* @__PURE__ */
|
|
7314
|
+
children: /* @__PURE__ */ jsx36(X9, { className: "w-3 h-3" })
|
|
6717
7315
|
}
|
|
6718
7316
|
),
|
|
6719
|
-
/* @__PURE__ */
|
|
6720
|
-
/* @__PURE__ */
|
|
7317
|
+
/* @__PURE__ */ jsxs31("div", { className: cn("mx-auto mb-2 overflow-hidden rounded-md", previewSizes[previewSize]), children: [
|
|
7318
|
+
/* @__PURE__ */ jsx36(
|
|
6721
7319
|
"img",
|
|
6722
7320
|
{
|
|
6723
7321
|
src: image.url,
|
|
@@ -6730,18 +7328,18 @@ function ImageUpload({
|
|
|
6730
7328
|
}
|
|
6731
7329
|
}
|
|
6732
7330
|
),
|
|
6733
|
-
/* @__PURE__ */
|
|
7331
|
+
/* @__PURE__ */ jsx36("div", { className: "hidden w-full h-full bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx36(ImageIcon, { className: "w-8 h-8 text-muted-foreground" }) })
|
|
6734
7332
|
] }),
|
|
6735
|
-
/* @__PURE__ */
|
|
6736
|
-
/* @__PURE__ */
|
|
6737
|
-
/* @__PURE__ */
|
|
6738
|
-
image.width && image.height && /* @__PURE__ */
|
|
7333
|
+
/* @__PURE__ */ jsxs31("div", { className: "space-y-1", children: [
|
|
7334
|
+
/* @__PURE__ */ jsx36("p", { className: "text-xs font-medium truncate", title: image.originalName, children: image.originalName }),
|
|
7335
|
+
/* @__PURE__ */ jsx36("p", { className: "text-xs text-muted-foreground", children: image.formattedSize }),
|
|
7336
|
+
image.width && image.height && /* @__PURE__ */ jsxs31("p", { className: "text-xs text-muted-foreground", children: [
|
|
6739
7337
|
image.width,
|
|
6740
7338
|
" \xD7 ",
|
|
6741
7339
|
image.height
|
|
6742
7340
|
] })
|
|
6743
7341
|
] }),
|
|
6744
|
-
/* @__PURE__ */
|
|
7342
|
+
/* @__PURE__ */ jsx36("div", { className: "absolute top-1 left-1 w-5 h-5 bg-success rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx36(Check7, { className: "w-3 h-3 text-success-foreground" }) })
|
|
6745
7343
|
]
|
|
6746
7344
|
},
|
|
6747
7345
|
image.id
|
|
@@ -6751,9 +7349,9 @@ function ImageUpload({
|
|
|
6751
7349
|
}
|
|
6752
7350
|
|
|
6753
7351
|
// ../../components/ui/Carousel.tsx
|
|
6754
|
-
import * as
|
|
6755
|
-
import { ChevronLeft as
|
|
6756
|
-
import { Fragment as
|
|
7352
|
+
import * as React29 from "react";
|
|
7353
|
+
import { ChevronLeft as ChevronLeft4, ChevronRight as ChevronRight6 } from "lucide-react";
|
|
7354
|
+
import { Fragment as Fragment11, jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
6757
7355
|
function Carousel({
|
|
6758
7356
|
children,
|
|
6759
7357
|
autoScroll = true,
|
|
@@ -6774,19 +7372,19 @@ function Carousel({
|
|
|
6774
7372
|
thumbnailRenderer,
|
|
6775
7373
|
ariaLabel = "Carousel"
|
|
6776
7374
|
}) {
|
|
6777
|
-
const [currentIndex, setCurrentIndex] =
|
|
6778
|
-
const [isPaused, setIsPaused] =
|
|
6779
|
-
const [isDragging, setIsDragging] =
|
|
6780
|
-
const [startPos, setStartPos] =
|
|
6781
|
-
const [currentTranslate, setCurrentTranslate] =
|
|
6782
|
-
const [prevTranslate, setPrevTranslate] =
|
|
6783
|
-
const progressElRef =
|
|
6784
|
-
const carouselRef =
|
|
6785
|
-
const rafRef =
|
|
6786
|
-
const totalSlides =
|
|
7375
|
+
const [currentIndex, setCurrentIndex] = React29.useState(0);
|
|
7376
|
+
const [isPaused, setIsPaused] = React29.useState(false);
|
|
7377
|
+
const [isDragging, setIsDragging] = React29.useState(false);
|
|
7378
|
+
const [startPos, setStartPos] = React29.useState(0);
|
|
7379
|
+
const [currentTranslate, setCurrentTranslate] = React29.useState(0);
|
|
7380
|
+
const [prevTranslate, setPrevTranslate] = React29.useState(0);
|
|
7381
|
+
const progressElRef = React29.useRef(null);
|
|
7382
|
+
const carouselRef = React29.useRef(null);
|
|
7383
|
+
const rafRef = React29.useRef(null);
|
|
7384
|
+
const totalSlides = React29.Children.count(children);
|
|
6787
7385
|
const maxIndex = Math.max(0, totalSlides - slidesToShow);
|
|
6788
7386
|
const isHorizontal = orientation === "horizontal";
|
|
6789
|
-
const scrollPrev =
|
|
7387
|
+
const scrollPrev = React29.useCallback(() => {
|
|
6790
7388
|
setCurrentIndex((prev) => {
|
|
6791
7389
|
if (prev === 0) {
|
|
6792
7390
|
return loop ? maxIndex : 0;
|
|
@@ -6794,7 +7392,7 @@ function Carousel({
|
|
|
6794
7392
|
return Math.max(0, prev - slidesToScroll);
|
|
6795
7393
|
});
|
|
6796
7394
|
}, [loop, maxIndex, slidesToScroll]);
|
|
6797
|
-
const scrollNext =
|
|
7395
|
+
const scrollNext = React29.useCallback(() => {
|
|
6798
7396
|
setCurrentIndex((prev) => {
|
|
6799
7397
|
if (prev >= maxIndex) {
|
|
6800
7398
|
return loop ? 0 : maxIndex;
|
|
@@ -6802,13 +7400,13 @@ function Carousel({
|
|
|
6802
7400
|
return Math.min(maxIndex, prev + slidesToScroll);
|
|
6803
7401
|
});
|
|
6804
7402
|
}, [loop, maxIndex, slidesToScroll]);
|
|
6805
|
-
const scrollTo =
|
|
7403
|
+
const scrollTo = React29.useCallback(
|
|
6806
7404
|
(index) => {
|
|
6807
7405
|
setCurrentIndex(Math.min(maxIndex, Math.max(0, index)));
|
|
6808
7406
|
},
|
|
6809
7407
|
[maxIndex]
|
|
6810
7408
|
);
|
|
6811
|
-
|
|
7409
|
+
React29.useEffect(() => {
|
|
6812
7410
|
const handleKeyDown = (e) => {
|
|
6813
7411
|
if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
6814
7412
|
e.preventDefault();
|
|
@@ -6830,7 +7428,7 @@ function Carousel({
|
|
|
6830
7428
|
return () => carousel.removeEventListener("keydown", handleKeyDown);
|
|
6831
7429
|
}
|
|
6832
7430
|
}, [scrollPrev, scrollNext, scrollTo, maxIndex]);
|
|
6833
|
-
|
|
7431
|
+
React29.useEffect(() => {
|
|
6834
7432
|
const stop = () => {
|
|
6835
7433
|
if (rafRef.current != null) {
|
|
6836
7434
|
cancelAnimationFrame(rafRef.current);
|
|
@@ -6889,7 +7487,7 @@ function Carousel({
|
|
|
6889
7487
|
setCurrentTranslate(0);
|
|
6890
7488
|
setPrevTranslate(0);
|
|
6891
7489
|
};
|
|
6892
|
-
|
|
7490
|
+
React29.useEffect(() => {
|
|
6893
7491
|
onSlideChange?.(currentIndex);
|
|
6894
7492
|
}, [currentIndex, onSlideChange]);
|
|
6895
7493
|
const getAnimationStyles = () => {
|
|
@@ -6911,7 +7509,7 @@ function Carousel({
|
|
|
6911
7509
|
};
|
|
6912
7510
|
};
|
|
6913
7511
|
const slideWidth = 100 / slidesToShow;
|
|
6914
|
-
return /* @__PURE__ */
|
|
7512
|
+
return /* @__PURE__ */ jsxs32(
|
|
6915
7513
|
"div",
|
|
6916
7514
|
{
|
|
6917
7515
|
ref: carouselRef,
|
|
@@ -6923,8 +7521,8 @@ function Carousel({
|
|
|
6923
7521
|
"aria-roledescription": "carousel",
|
|
6924
7522
|
tabIndex: 0,
|
|
6925
7523
|
children: [
|
|
6926
|
-
showProgress && autoScroll && /* @__PURE__ */
|
|
6927
|
-
/* @__PURE__ */
|
|
7524
|
+
showProgress && autoScroll && /* @__PURE__ */ jsx37("div", { className: "absolute top-0 left-0 right-0 h-1 bg-muted z-20", children: /* @__PURE__ */ jsx37("div", { ref: progressElRef, className: "h-full bg-primary", style: { width: "0%" } }) }),
|
|
7525
|
+
/* @__PURE__ */ jsx37(
|
|
6928
7526
|
"div",
|
|
6929
7527
|
{
|
|
6930
7528
|
className: cn("flex", isHorizontal ? "flex-row" : "flex-col", containerClassName),
|
|
@@ -6939,7 +7537,7 @@ function Carousel({
|
|
|
6939
7537
|
role: "group",
|
|
6940
7538
|
"aria-atomic": "false",
|
|
6941
7539
|
"aria-live": autoScroll ? "off" : "polite",
|
|
6942
|
-
children:
|
|
7540
|
+
children: React29.Children.map(children, (child, idx) => /* @__PURE__ */ jsx37(
|
|
6943
7541
|
"div",
|
|
6944
7542
|
{
|
|
6945
7543
|
className: cn(
|
|
@@ -6962,14 +7560,14 @@ function Carousel({
|
|
|
6962
7560
|
))
|
|
6963
7561
|
}
|
|
6964
7562
|
),
|
|
6965
|
-
showArrows && totalSlides > slidesToShow && /* @__PURE__ */
|
|
6966
|
-
/* @__PURE__ */
|
|
7563
|
+
showArrows && totalSlides > slidesToShow && /* @__PURE__ */ jsxs32(Fragment11, { children: [
|
|
7564
|
+
/* @__PURE__ */ jsx37(
|
|
6967
7565
|
Button_default,
|
|
6968
7566
|
{
|
|
6969
7567
|
onClick: scrollPrev,
|
|
6970
7568
|
variant: "ghost",
|
|
6971
7569
|
size: "icon",
|
|
6972
|
-
icon:
|
|
7570
|
+
icon: ChevronLeft4,
|
|
6973
7571
|
noHoverOverlay: true,
|
|
6974
7572
|
disabled: !loop && currentIndex === 0,
|
|
6975
7573
|
className: cn(
|
|
@@ -6979,13 +7577,13 @@ function Carousel({
|
|
|
6979
7577
|
"aria-label": "Previous slide"
|
|
6980
7578
|
}
|
|
6981
7579
|
),
|
|
6982
|
-
/* @__PURE__ */
|
|
7580
|
+
/* @__PURE__ */ jsx37(
|
|
6983
7581
|
Button_default,
|
|
6984
7582
|
{
|
|
6985
7583
|
onClick: scrollNext,
|
|
6986
7584
|
variant: "ghost",
|
|
6987
7585
|
size: "icon",
|
|
6988
|
-
icon:
|
|
7586
|
+
icon: ChevronRight6,
|
|
6989
7587
|
noHoverOverlay: true,
|
|
6990
7588
|
disabled: !loop && currentIndex >= maxIndex,
|
|
6991
7589
|
className: cn(
|
|
@@ -6996,7 +7594,7 @@ function Carousel({
|
|
|
6996
7594
|
}
|
|
6997
7595
|
)
|
|
6998
7596
|
] }),
|
|
6999
|
-
showDots && totalSlides > slidesToShow && /* @__PURE__ */
|
|
7597
|
+
showDots && totalSlides > slidesToShow && /* @__PURE__ */ jsx37(
|
|
7000
7598
|
"div",
|
|
7001
7599
|
{
|
|
7002
7600
|
className: cn(
|
|
@@ -7005,7 +7603,7 @@ function Carousel({
|
|
|
7005
7603
|
),
|
|
7006
7604
|
role: "tablist",
|
|
7007
7605
|
"aria-label": "Carousel pagination",
|
|
7008
|
-
children: Array.from({ length: maxIndex + 1 }, (_, idx) => /* @__PURE__ */
|
|
7606
|
+
children: Array.from({ length: maxIndex + 1 }, (_, idx) => /* @__PURE__ */ jsx37(
|
|
7009
7607
|
"button",
|
|
7010
7608
|
{
|
|
7011
7609
|
onClick: () => scrollTo(idx),
|
|
@@ -7022,14 +7620,14 @@ function Carousel({
|
|
|
7022
7620
|
))
|
|
7023
7621
|
}
|
|
7024
7622
|
),
|
|
7025
|
-
showThumbnails && totalSlides > slidesToShow && /* @__PURE__ */
|
|
7623
|
+
showThumbnails && totalSlides > slidesToShow && /* @__PURE__ */ jsx37(
|
|
7026
7624
|
"div",
|
|
7027
7625
|
{
|
|
7028
7626
|
className: cn(
|
|
7029
7627
|
"absolute bottom-0 left-0 right-0 flex gap-2 p-4 bg-gradient-to-t from-black/50 to-transparent overflow-x-auto",
|
|
7030
7628
|
isHorizontal ? "flex-row" : "flex-col"
|
|
7031
7629
|
),
|
|
7032
|
-
children:
|
|
7630
|
+
children: React29.Children.map(children, (child, idx) => /* @__PURE__ */ jsx37(
|
|
7033
7631
|
"button",
|
|
7034
7632
|
{
|
|
7035
7633
|
onClick: () => scrollTo(idx),
|
|
@@ -7050,8 +7648,8 @@ function Carousel({
|
|
|
7050
7648
|
}
|
|
7051
7649
|
|
|
7052
7650
|
// ../../components/ui/FallingIcons.tsx
|
|
7053
|
-
import
|
|
7054
|
-
import { jsx as
|
|
7651
|
+
import React30 from "react";
|
|
7652
|
+
import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
7055
7653
|
var DEFAULT_COUNT = 24;
|
|
7056
7654
|
var DEFAULT_SPEED_RANGE = [6, 14];
|
|
7057
7655
|
var DEFAULT_SIZE_RANGE = [14, 28];
|
|
@@ -7078,10 +7676,10 @@ function FallingIcons({
|
|
|
7078
7676
|
physics,
|
|
7079
7677
|
easingFunction = "linear"
|
|
7080
7678
|
}) {
|
|
7081
|
-
const uid =
|
|
7082
|
-
const containerRef =
|
|
7083
|
-
const [fallDist, setFallDist] =
|
|
7084
|
-
const idRef =
|
|
7679
|
+
const uid = React30.useId().replace(/[:]/g, "");
|
|
7680
|
+
const containerRef = React30.useRef(null);
|
|
7681
|
+
const [fallDist, setFallDist] = React30.useState(null);
|
|
7682
|
+
const idRef = React30.useRef(1);
|
|
7085
7683
|
const gravity = physics?.gravity ?? 1;
|
|
7086
7684
|
const windDirection = physics?.windDirection ?? 0;
|
|
7087
7685
|
const windStrength = physics?.windStrength ?? 0;
|
|
@@ -7095,7 +7693,7 @@ function FallingIcons({
|
|
|
7095
7693
|
bounce: "cubic-bezier(0.68, -0.55, 0.265, 1.55)",
|
|
7096
7694
|
elastic: "cubic-bezier(0.175, 0.885, 0.32, 1.275)"
|
|
7097
7695
|
};
|
|
7098
|
-
const makeParticle =
|
|
7696
|
+
const makeParticle = React30.useCallback(() => {
|
|
7099
7697
|
const rnd = (min, max) => min + Math.random() * (max - min);
|
|
7100
7698
|
return {
|
|
7101
7699
|
leftPct: rnd(0, 100),
|
|
@@ -7109,12 +7707,12 @@ function FallingIcons({
|
|
|
7109
7707
|
key: idRef.current++
|
|
7110
7708
|
};
|
|
7111
7709
|
}, [sizeRange, speedRange, horizontalDrift, gravity, windDirection, windStrength]);
|
|
7112
|
-
const [particles, setParticles] =
|
|
7113
|
-
|
|
7710
|
+
const [particles, setParticles] = React30.useState([]);
|
|
7711
|
+
React30.useEffect(() => {
|
|
7114
7712
|
const arr = Array.from({ length: Math.max(0, count) }).map(() => makeParticle());
|
|
7115
7713
|
setParticles(arr);
|
|
7116
7714
|
}, [count, makeParticle]);
|
|
7117
|
-
|
|
7715
|
+
React30.useEffect(() => {
|
|
7118
7716
|
if (fullScreen) {
|
|
7119
7717
|
const measure2 = () => setFallDist(window.innerHeight + 200);
|
|
7120
7718
|
measure2();
|
|
@@ -7139,15 +7737,15 @@ function FallingIcons({
|
|
|
7139
7737
|
const SpinName = `uv-spin-${uid}`;
|
|
7140
7738
|
const PopName = `uv-pop-${uid}`;
|
|
7141
7739
|
const PhysicsSpinName = `uv-physics-spin-${uid}`;
|
|
7142
|
-
const glowStyles =
|
|
7740
|
+
const glowStyles = React30.useMemo(() => {
|
|
7143
7741
|
if (!glow) return {};
|
|
7144
7742
|
const intensity = Math.max(0, Math.min(1, glowIntensity));
|
|
7145
7743
|
return {
|
|
7146
7744
|
filter: `drop-shadow(0 0 ${4 * intensity}px ${glowColor}) drop-shadow(0 0 ${8 * intensity}px ${glowColor})`
|
|
7147
7745
|
};
|
|
7148
7746
|
}, [glow, glowColor, glowIntensity]);
|
|
7149
|
-
const FallbackIcon =
|
|
7150
|
-
const TheIcon = imageUrl ? ({ className: imgClassName }) => /* @__PURE__ */
|
|
7747
|
+
const FallbackIcon = React30.useMemo(() => (props) => /* @__PURE__ */ jsx38("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", ...props, children: /* @__PURE__ */ jsx38("circle", { cx: "12", cy: "12", r: "10" }) }), []);
|
|
7748
|
+
const TheIcon = imageUrl ? ({ className: imgClassName }) => /* @__PURE__ */ jsx38(
|
|
7151
7749
|
"img",
|
|
7152
7750
|
{
|
|
7153
7751
|
src: imageUrl,
|
|
@@ -7156,7 +7754,7 @@ function FallingIcons({
|
|
|
7156
7754
|
draggable: false
|
|
7157
7755
|
}
|
|
7158
7756
|
) : Icon || FallbackIcon;
|
|
7159
|
-
return /* @__PURE__ */
|
|
7757
|
+
return /* @__PURE__ */ jsxs33(
|
|
7160
7758
|
"div",
|
|
7161
7759
|
{
|
|
7162
7760
|
ref: containerRef,
|
|
@@ -7166,7 +7764,7 @@ function FallingIcons({
|
|
|
7166
7764
|
),
|
|
7167
7765
|
style: { zIndex },
|
|
7168
7766
|
children: [
|
|
7169
|
-
/* @__PURE__ */
|
|
7767
|
+
/* @__PURE__ */ jsx38("style", { children: `
|
|
7170
7768
|
@keyframes ${FallName} {
|
|
7171
7769
|
0% { transform: translate3d(0, -10vh, 0); opacity: 0; }
|
|
7172
7770
|
10% { opacity: 1; }
|
|
@@ -7199,7 +7797,7 @@ function FallingIcons({
|
|
|
7199
7797
|
}
|
|
7200
7798
|
}
|
|
7201
7799
|
` }),
|
|
7202
|
-
/* @__PURE__ */
|
|
7800
|
+
/* @__PURE__ */ jsx38(
|
|
7203
7801
|
"div",
|
|
7204
7802
|
{
|
|
7205
7803
|
className: cn(
|
|
@@ -7220,12 +7818,12 @@ function FallingIcons({
|
|
|
7220
7818
|
});
|
|
7221
7819
|
};
|
|
7222
7820
|
const trailParticles = trail ? Array.from({ length: Math.min(5, Math.max(1, trailLength)) }) : [];
|
|
7223
|
-
return /* @__PURE__ */
|
|
7821
|
+
return /* @__PURE__ */ jsxs33(React30.Fragment, { children: [
|
|
7224
7822
|
trail && trailParticles.map((_, trailIndex) => {
|
|
7225
7823
|
const trailDelay = p.delay - (trailIndex + 1) * 0.15;
|
|
7226
7824
|
const trailOpacity = 1 - (trailIndex + 1) * (1 / (trailParticles.length + 1));
|
|
7227
7825
|
const trailScale = 1 - (trailIndex + 1) * 0.15;
|
|
7228
|
-
return /* @__PURE__ */
|
|
7826
|
+
return /* @__PURE__ */ jsx38(
|
|
7229
7827
|
"span",
|
|
7230
7828
|
{
|
|
7231
7829
|
className: cn("absolute top-0 will-change-transform pointer-events-none uv-falling-particle", colorClassName),
|
|
@@ -7239,7 +7837,7 @@ function FallingIcons({
|
|
|
7239
7837
|
opacity: trailOpacity * 0.4,
|
|
7240
7838
|
["--fall"]: `${fallDist ?? (typeof window !== "undefined" ? window.innerHeight + 200 : 1200)}px`
|
|
7241
7839
|
},
|
|
7242
|
-
children: /* @__PURE__ */
|
|
7840
|
+
children: /* @__PURE__ */ jsx38(
|
|
7243
7841
|
"span",
|
|
7244
7842
|
{
|
|
7245
7843
|
className: "inline-block uv-sway",
|
|
@@ -7251,7 +7849,7 @@ function FallingIcons({
|
|
|
7251
7849
|
animationIterationCount: "infinite",
|
|
7252
7850
|
["--amp"]: `${Math.round(p.driftAmp)}px`
|
|
7253
7851
|
},
|
|
7254
|
-
children: /* @__PURE__ */
|
|
7852
|
+
children: /* @__PURE__ */ jsx38(
|
|
7255
7853
|
"span",
|
|
7256
7854
|
{
|
|
7257
7855
|
className: "block",
|
|
@@ -7260,7 +7858,7 @@ function FallingIcons({
|
|
|
7260
7858
|
height: p.size,
|
|
7261
7859
|
...glowStyles
|
|
7262
7860
|
},
|
|
7263
|
-
children: /* @__PURE__ */
|
|
7861
|
+
children: /* @__PURE__ */ jsx38(TheIcon, { className: cn("w-full h-full text-primary/70", colorClassName) })
|
|
7264
7862
|
}
|
|
7265
7863
|
)
|
|
7266
7864
|
}
|
|
@@ -7269,7 +7867,7 @@ function FallingIcons({
|
|
|
7269
7867
|
`${p.key}-trail-${trailIndex}`
|
|
7270
7868
|
);
|
|
7271
7869
|
}),
|
|
7272
|
-
/* @__PURE__ */
|
|
7870
|
+
/* @__PURE__ */ jsx38(
|
|
7273
7871
|
"span",
|
|
7274
7872
|
{
|
|
7275
7873
|
className: cn("absolute top-0 will-change-transform pointer-events-auto uv-falling-particle", colorClassName),
|
|
@@ -7295,7 +7893,7 @@ function FallingIcons({
|
|
|
7295
7893
|
return next;
|
|
7296
7894
|
});
|
|
7297
7895
|
},
|
|
7298
|
-
children: /* @__PURE__ */
|
|
7896
|
+
children: /* @__PURE__ */ jsx38(
|
|
7299
7897
|
"span",
|
|
7300
7898
|
{
|
|
7301
7899
|
className: "inline-block uv-sway",
|
|
@@ -7307,7 +7905,7 @@ function FallingIcons({
|
|
|
7307
7905
|
animationIterationCount: "infinite",
|
|
7308
7906
|
["--amp"]: `${Math.round(p.driftAmp)}px`
|
|
7309
7907
|
},
|
|
7310
|
-
children: /* @__PURE__ */
|
|
7908
|
+
children: /* @__PURE__ */ jsx38(
|
|
7311
7909
|
"span",
|
|
7312
7910
|
{
|
|
7313
7911
|
className: cn(
|
|
@@ -7323,7 +7921,7 @@ function FallingIcons({
|
|
|
7323
7921
|
["--popName"]: PopName,
|
|
7324
7922
|
...glowStyles
|
|
7325
7923
|
},
|
|
7326
|
-
children: /* @__PURE__ */
|
|
7924
|
+
children: /* @__PURE__ */ jsx38(TheIcon, { className: cn("w-full h-full text-primary/70", colorClassName) })
|
|
7327
7925
|
}
|
|
7328
7926
|
)
|
|
7329
7927
|
}
|
|
@@ -7339,23 +7937,1340 @@ function FallingIcons({
|
|
|
7339
7937
|
);
|
|
7340
7938
|
}
|
|
7341
7939
|
|
|
7940
|
+
// ../../components/ui/List.tsx
|
|
7941
|
+
import * as React31 from "react";
|
|
7942
|
+
import { ChevronRight as ChevronRight7 } from "lucide-react";
|
|
7943
|
+
import { Fragment as Fragment12, jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
7944
|
+
var SIZE_STYLES2 = {
|
|
7945
|
+
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" },
|
|
7946
|
+
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" },
|
|
7947
|
+
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" },
|
|
7948
|
+
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" }
|
|
7949
|
+
};
|
|
7950
|
+
var BADGE_VARIANTS = {
|
|
7951
|
+
default: "bg-muted text-muted-foreground",
|
|
7952
|
+
success: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
7953
|
+
warning: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400",
|
|
7954
|
+
error: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
|
|
7955
|
+
info: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"
|
|
7956
|
+
};
|
|
7957
|
+
var ListItemSkeleton = ({ size }) => {
|
|
7958
|
+
const sz = SIZE_STYLES2[size];
|
|
7959
|
+
return /* @__PURE__ */ jsxs34("div", { className: cn("flex items-center gap-3 animate-pulse", sz.itemPad), children: [
|
|
7960
|
+
/* @__PURE__ */ jsx39("div", { className: cn("rounded-full bg-muted shrink-0", sz.avatar) }),
|
|
7961
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex-1 space-y-2", children: [
|
|
7962
|
+
/* @__PURE__ */ jsx39("div", { className: "h-4 bg-muted rounded w-3/4" }),
|
|
7963
|
+
/* @__PURE__ */ jsx39("div", { className: "h-3 bg-muted rounded w-1/2" })
|
|
7964
|
+
] })
|
|
7965
|
+
] });
|
|
7966
|
+
};
|
|
7967
|
+
var ListRoot = React31.forwardRef(
|
|
7968
|
+
({
|
|
7969
|
+
as = "ul",
|
|
7970
|
+
ordered,
|
|
7971
|
+
variant = "plain",
|
|
7972
|
+
size = "md",
|
|
7973
|
+
divided = false,
|
|
7974
|
+
inset = false,
|
|
7975
|
+
hoverable = true,
|
|
7976
|
+
loading: loading2 = false,
|
|
7977
|
+
loadingCount = 3,
|
|
7978
|
+
emptyText,
|
|
7979
|
+
dense = false,
|
|
7980
|
+
className,
|
|
7981
|
+
children,
|
|
7982
|
+
...rest
|
|
7983
|
+
}, ref) => {
|
|
7984
|
+
const Comp = ordered ? "ol" : as;
|
|
7985
|
+
const childCount = React31.Children.count(children);
|
|
7986
|
+
const hasChildren = childCount > 0;
|
|
7987
|
+
const variantClasses = {
|
|
7988
|
+
plain: "",
|
|
7989
|
+
outlined: "rounded-lg md:rounded-xl bg-card text-card-foreground border border-border shadow-sm",
|
|
7990
|
+
soft: "rounded-lg bg-muted/40 border border-border/60",
|
|
7991
|
+
bordered: "border border-border rounded-lg",
|
|
7992
|
+
card: "rounded-lg bg-card shadow-md border border-border",
|
|
7993
|
+
flush: "",
|
|
7994
|
+
striped: "rounded-lg border border-border overflow-hidden"
|
|
7995
|
+
};
|
|
7996
|
+
if (loading2) {
|
|
7997
|
+
return /* @__PURE__ */ jsx39(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__ */ jsx39(ListItemSkeleton, { size }, i)) });
|
|
7998
|
+
}
|
|
7999
|
+
if (!hasChildren && emptyText) {
|
|
8000
|
+
return /* @__PURE__ */ jsx39(Comp, { ref, className: cn("group/list", variantClasses[variant], inset && "p-1.5 md:p-2", className), ...rest, children: /* @__PURE__ */ jsx39("div", { className: "text-center py-8 text-muted-foreground text-sm", children: emptyText }) });
|
|
8001
|
+
}
|
|
8002
|
+
return /* @__PURE__ */ jsx39(
|
|
8003
|
+
Comp,
|
|
8004
|
+
{
|
|
8005
|
+
ref,
|
|
8006
|
+
className: cn(
|
|
8007
|
+
"group/list",
|
|
8008
|
+
variantClasses[variant],
|
|
8009
|
+
inset && "p-1.5 md:p-2",
|
|
8010
|
+
divided && "divide-y divide-border/60",
|
|
8011
|
+
variant === "striped" && "[&>*:nth-child(even)]:bg-muted/30",
|
|
8012
|
+
className
|
|
8013
|
+
),
|
|
8014
|
+
...rest,
|
|
8015
|
+
children: React31.Children.map(children, (child, idx) => {
|
|
8016
|
+
if (!React31.isValidElement(child)) return child;
|
|
8017
|
+
const childClass = cn(
|
|
8018
|
+
child.props?.className,
|
|
8019
|
+
hoverable && variant !== "flush" && "hover:bg-accent/50 focus:bg-accent/60 focus:outline-none transition-colors",
|
|
8020
|
+
variant === "flush" && "hover:bg-accent/30"
|
|
8021
|
+
);
|
|
8022
|
+
return React31.cloneElement(child, {
|
|
8023
|
+
className: childClass,
|
|
8024
|
+
"data-first": idx === 0 ? "true" : void 0,
|
|
8025
|
+
"data-last": idx === childCount - 1 ? "true" : void 0,
|
|
8026
|
+
"data-size": size,
|
|
8027
|
+
"data-dense": dense ? "true" : void 0
|
|
8028
|
+
});
|
|
8029
|
+
})
|
|
8030
|
+
}
|
|
8031
|
+
);
|
|
8032
|
+
}
|
|
8033
|
+
);
|
|
8034
|
+
ListRoot.displayName = "List";
|
|
8035
|
+
var ListItem = React31.forwardRef(
|
|
8036
|
+
({
|
|
8037
|
+
as = "li",
|
|
8038
|
+
selected = false,
|
|
8039
|
+
disabled = false,
|
|
8040
|
+
href,
|
|
8041
|
+
label,
|
|
8042
|
+
description,
|
|
8043
|
+
leftIcon: Left,
|
|
8044
|
+
rightIcon: Right,
|
|
8045
|
+
avatar,
|
|
8046
|
+
badge,
|
|
8047
|
+
badgeVariant = "default",
|
|
8048
|
+
action,
|
|
8049
|
+
collapsible = false,
|
|
8050
|
+
expanded: controlledExpanded,
|
|
8051
|
+
onExpandChange,
|
|
8052
|
+
expandContent,
|
|
8053
|
+
className,
|
|
8054
|
+
children,
|
|
8055
|
+
...rest
|
|
8056
|
+
}, ref) => {
|
|
8057
|
+
const [internalExpanded, setInternalExpanded] = React31.useState(false);
|
|
8058
|
+
const isExpanded = controlledExpanded !== void 0 ? controlledExpanded : internalExpanded;
|
|
8059
|
+
const sizeAttr = rest["data-size"];
|
|
8060
|
+
const denseAttr = rest["data-dense"];
|
|
8061
|
+
const isDense = denseAttr === "true";
|
|
8062
|
+
const resolvedSize = sizeAttr && (sizeAttr === "xs" || sizeAttr === "sm" || sizeAttr === "md" || sizeAttr === "lg") ? sizeAttr : "md";
|
|
8063
|
+
const sz = SIZE_STYLES2[resolvedSize];
|
|
8064
|
+
const padding = isDense ? sz.densePad : sz.itemPad;
|
|
8065
|
+
const toggleExpanded = () => {
|
|
8066
|
+
const newExpanded = !isExpanded;
|
|
8067
|
+
if (onExpandChange) {
|
|
8068
|
+
onExpandChange(newExpanded);
|
|
8069
|
+
} else {
|
|
8070
|
+
setInternalExpanded(newExpanded);
|
|
8071
|
+
}
|
|
8072
|
+
};
|
|
8073
|
+
const inner = /* @__PURE__ */ jsxs34(Fragment12, { children: [
|
|
8074
|
+
/* @__PURE__ */ jsxs34("div", { className: cn("flex items-center gap-3", padding, "group/item relative"), children: [
|
|
8075
|
+
avatar && /* @__PURE__ */ jsx39("div", { className: cn("shrink-0", sz.avatar), children: typeof avatar === "string" ? /* @__PURE__ */ jsx39("img", { src: avatar, alt: "", className: cn("rounded-full object-cover", sz.avatar) }) : avatar }),
|
|
8076
|
+
Left && !avatar && /* @__PURE__ */ jsx39("span", { className: cn("text-muted-foreground shrink-0", sz.icon), children: /* @__PURE__ */ jsx39(Left, { className: cn(sz.icon) }) }),
|
|
8077
|
+
/* @__PURE__ */ jsxs34("div", { className: "min-w-0 flex-1", children: [
|
|
8078
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2", children: [
|
|
8079
|
+
label && /* @__PURE__ */ jsx39("div", { className: cn(sz.label, "text-foreground font-medium truncate"), children: label }),
|
|
8080
|
+
badge && /* @__PURE__ */ jsx39("span", { className: cn("px-2 py-0.5 rounded-full text-[11px] font-medium shrink-0", BADGE_VARIANTS[badgeVariant]), children: badge })
|
|
8081
|
+
] }),
|
|
8082
|
+
description && /* @__PURE__ */ jsx39("div", { className: cn(sz.desc, "text-muted-foreground truncate mt-0.5"), children: description }),
|
|
8083
|
+
children && /* @__PURE__ */ jsx39("div", { className: "mt-1", children })
|
|
8084
|
+
] }),
|
|
8085
|
+
action && /* @__PURE__ */ jsx39("div", { className: "opacity-0 group-hover/item:opacity-100 transition-opacity shrink-0", children: action }),
|
|
8086
|
+
collapsible ? /* @__PURE__ */ jsx39(
|
|
8087
|
+
"span",
|
|
8088
|
+
{
|
|
8089
|
+
role: "button",
|
|
8090
|
+
"aria-label": "Toggle",
|
|
8091
|
+
tabIndex: 0,
|
|
8092
|
+
onClick: (e) => {
|
|
8093
|
+
e.stopPropagation();
|
|
8094
|
+
toggleExpanded();
|
|
8095
|
+
},
|
|
8096
|
+
onKeyDown: (e) => {
|
|
8097
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8098
|
+
e.preventDefault();
|
|
8099
|
+
e.stopPropagation();
|
|
8100
|
+
toggleExpanded();
|
|
8101
|
+
}
|
|
8102
|
+
},
|
|
8103
|
+
className: cn("text-muted-foreground shrink-0 transition-transform cursor-pointer select-none", sz.icon, isExpanded && "rotate-90"),
|
|
8104
|
+
children: /* @__PURE__ */ jsx39(ChevronRight7, { className: cn(sz.icon) })
|
|
8105
|
+
}
|
|
8106
|
+
) : Right && /* @__PURE__ */ jsx39("span", { className: cn("text-muted-foreground shrink-0", sz.icon), children: /* @__PURE__ */ jsx39(Right, { className: cn(sz.icon) }) })
|
|
8107
|
+
] }),
|
|
8108
|
+
collapsible && isExpanded && expandContent && /* @__PURE__ */ jsx39("div", { className: cn("border-t border-border/50 bg-muted/20", padding, "pt-3"), children: expandContent })
|
|
8109
|
+
] });
|
|
8110
|
+
const baseCls = cn(
|
|
8111
|
+
"relative w-full",
|
|
8112
|
+
selected && "bg-primary/10 ring-1 ring-primary/30",
|
|
8113
|
+
disabled && "opacity-60 cursor-not-allowed",
|
|
8114
|
+
className
|
|
8115
|
+
);
|
|
8116
|
+
if (href) {
|
|
8117
|
+
const A = as === "a" ? "a" : "a";
|
|
8118
|
+
return /* @__PURE__ */ jsx39(A, { ref, href, className: cn(baseCls, "block"), ...rest, children: inner });
|
|
8119
|
+
}
|
|
8120
|
+
if (as === "button" || collapsible) {
|
|
8121
|
+
return /* @__PURE__ */ jsx39(
|
|
8122
|
+
"button",
|
|
8123
|
+
{
|
|
8124
|
+
ref,
|
|
8125
|
+
type: "button",
|
|
8126
|
+
className: cn(baseCls, "text-left block w-full"),
|
|
8127
|
+
onClick: collapsible ? toggleExpanded : void 0,
|
|
8128
|
+
...rest,
|
|
8129
|
+
children: inner
|
|
8130
|
+
}
|
|
8131
|
+
);
|
|
8132
|
+
}
|
|
8133
|
+
const Comp = as;
|
|
8134
|
+
return /* @__PURE__ */ jsx39(Comp, { ref, className: baseCls, ...rest, children: inner });
|
|
8135
|
+
}
|
|
8136
|
+
);
|
|
8137
|
+
ListItem.displayName = "List.Item";
|
|
8138
|
+
var List = Object.assign(ListRoot, { Item: ListItem });
|
|
8139
|
+
var List_default = List;
|
|
8140
|
+
|
|
8141
|
+
// ../../components/ui/Watermark.tsx
|
|
8142
|
+
import * as React32 from "react";
|
|
8143
|
+
import { createPortal as createPortal9 } from "react-dom";
|
|
8144
|
+
import { Fragment as Fragment13, jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
8145
|
+
var PRESETS2 = {
|
|
8146
|
+
confidential: { text: "CONFIDENTIAL", color: "rgba(220, 38, 38, 0.15)", rotate: -22, fontSize: 16, fontWeight: "bold" },
|
|
8147
|
+
draft: { text: "DRAFT", color: "rgba(59, 130, 246, 0.15)", rotate: -22, fontSize: 18, fontWeight: "bold" },
|
|
8148
|
+
sample: { text: "SAMPLE", color: "rgba(168, 85, 247, 0.15)", rotate: -22, fontSize: 16, fontWeight: "600" },
|
|
8149
|
+
copyright: { text: "\xA9 Copyright", color: "rgba(0, 0, 0, 0.1)", rotate: 0, fontSize: 12, fontWeight: "normal" },
|
|
8150
|
+
doNotCopy: { text: "DO NOT COPY", color: "rgba(234, 88, 12, 0.15)", rotate: -22, fontSize: 14, fontWeight: "bold" },
|
|
8151
|
+
internal: { text: "INTERNAL USE ONLY", color: "rgba(156, 163, 175, 0.15)", rotate: -22, fontSize: 13, fontWeight: "600" }
|
|
8152
|
+
};
|
|
8153
|
+
function useWatermarkDataURL(opts) {
|
|
8154
|
+
const [url, setUrl] = React32.useState(null);
|
|
8155
|
+
React32.useEffect(() => {
|
|
8156
|
+
let cancelled = false;
|
|
8157
|
+
const text = opts.text;
|
|
8158
|
+
const image = opts.image;
|
|
8159
|
+
const width = opts.width ?? 180;
|
|
8160
|
+
const height = opts.height ?? 100;
|
|
8161
|
+
const gapX = opts.gapX ?? 16;
|
|
8162
|
+
const gapY = opts.gapY ?? 16;
|
|
8163
|
+
const rotate = opts.rotate ?? -22;
|
|
8164
|
+
const fontSize = opts.fontSize ?? 14;
|
|
8165
|
+
const fontFamily = opts.fontFamily ?? "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial";
|
|
8166
|
+
const fontWeight = opts.fontWeight ?? "normal";
|
|
8167
|
+
const fontStyle = opts.fontStyle ?? "normal";
|
|
8168
|
+
const color = opts.color ?? "rgba(0,0,0,0.15)";
|
|
8169
|
+
const gradient = opts.gradient;
|
|
8170
|
+
const pattern = opts.pattern ?? "diagonal";
|
|
8171
|
+
const tileW = width + gapX;
|
|
8172
|
+
const tileH = height + gapY;
|
|
8173
|
+
const canvas = document.createElement("canvas");
|
|
8174
|
+
canvas.width = tileW;
|
|
8175
|
+
canvas.height = tileH;
|
|
8176
|
+
const ctx = canvas.getContext("2d");
|
|
8177
|
+
if (!ctx) return;
|
|
8178
|
+
const drawText = () => {
|
|
8179
|
+
ctx.clearRect(0, 0, tileW, tileH);
|
|
8180
|
+
ctx.save();
|
|
8181
|
+
ctx.translate(tileW / 2, tileH / 2);
|
|
8182
|
+
if (pattern === "diagonal") {
|
|
8183
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
8184
|
+
} else if (pattern === "straight") {
|
|
8185
|
+
}
|
|
8186
|
+
if (text) {
|
|
8187
|
+
const textLines = Array.isArray(text) ? text : [text];
|
|
8188
|
+
ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
8189
|
+
ctx.textAlign = "center";
|
|
8190
|
+
ctx.textBaseline = "middle";
|
|
8191
|
+
if (gradient) {
|
|
8192
|
+
const splitStops = (input) => {
|
|
8193
|
+
const s = input.trim();
|
|
8194
|
+
let inside = s;
|
|
8195
|
+
const lg = s.toLowerCase();
|
|
8196
|
+
if (lg.startsWith("linear-gradient")) {
|
|
8197
|
+
const start = s.indexOf("(");
|
|
8198
|
+
const end = s.lastIndexOf(")");
|
|
8199
|
+
if (start >= 0 && end > start) inside = s.slice(start + 1, end);
|
|
8200
|
+
}
|
|
8201
|
+
const parts = [];
|
|
8202
|
+
let buf = "";
|
|
8203
|
+
let depth = 0;
|
|
8204
|
+
for (let i = 0; i < inside.length; i++) {
|
|
8205
|
+
const ch = inside[i];
|
|
8206
|
+
if (ch === "(") depth++;
|
|
8207
|
+
if (ch === ")") depth = Math.max(0, depth - 1);
|
|
8208
|
+
if (ch === "," && depth === 0) {
|
|
8209
|
+
parts.push(buf.trim());
|
|
8210
|
+
buf = "";
|
|
8211
|
+
} else {
|
|
8212
|
+
buf += ch;
|
|
8213
|
+
}
|
|
8214
|
+
}
|
|
8215
|
+
if (buf.trim()) parts.push(buf.trim());
|
|
8216
|
+
if (parts.length > 0) {
|
|
8217
|
+
const first = parts[0].toLowerCase();
|
|
8218
|
+
if (first.startsWith("to ") || first.endsWith("deg") || first.endsWith("rad")) {
|
|
8219
|
+
parts.shift();
|
|
8220
|
+
}
|
|
8221
|
+
}
|
|
8222
|
+
return parts.filter(Boolean);
|
|
8223
|
+
};
|
|
8224
|
+
const stops = splitStops(gradient);
|
|
8225
|
+
const gradientObj = ctx.createLinearGradient(0, -height / 2, 0, height / 2);
|
|
8226
|
+
stops.forEach((c, i) => {
|
|
8227
|
+
const tokens = c.split(/\s+/).filter(Boolean);
|
|
8228
|
+
const col = tokens[0];
|
|
8229
|
+
const pos = tokens[1] ? parseFloat(tokens[1]) / 100 : i / Math.max(1, stops.length - 1);
|
|
8230
|
+
try {
|
|
8231
|
+
gradientObj.addColorStop(isFinite(pos) ? Math.min(Math.max(pos, 0), 1) : i / Math.max(1, stops.length - 1), col);
|
|
8232
|
+
} catch {
|
|
8233
|
+
}
|
|
8234
|
+
});
|
|
8235
|
+
ctx.fillStyle = gradientObj;
|
|
8236
|
+
} else {
|
|
8237
|
+
ctx.fillStyle = color;
|
|
8238
|
+
}
|
|
8239
|
+
const lineHeight = fontSize * 1.2;
|
|
8240
|
+
const totalHeight = textLines.length * lineHeight;
|
|
8241
|
+
const startY = -(totalHeight / 2) + lineHeight / 2;
|
|
8242
|
+
textLines.forEach((line, index) => {
|
|
8243
|
+
const y = startY + index * lineHeight;
|
|
8244
|
+
ctx.fillText(line, 0, y, width);
|
|
8245
|
+
});
|
|
8246
|
+
}
|
|
8247
|
+
ctx.restore();
|
|
8248
|
+
if (!cancelled) setUrl(canvas.toDataURL());
|
|
8249
|
+
};
|
|
8250
|
+
if (image) {
|
|
8251
|
+
const img = new Image();
|
|
8252
|
+
img.crossOrigin = "anonymous";
|
|
8253
|
+
img.onload = () => {
|
|
8254
|
+
ctx.clearRect(0, 0, tileW, tileH);
|
|
8255
|
+
ctx.save();
|
|
8256
|
+
ctx.translate(tileW / 2, tileH / 2);
|
|
8257
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
8258
|
+
const drawW = width;
|
|
8259
|
+
const drawH = height;
|
|
8260
|
+
ctx.drawImage(img, -drawW / 2, -drawH / 2, drawW, drawH);
|
|
8261
|
+
ctx.restore();
|
|
8262
|
+
if (!cancelled) setUrl(canvas.toDataURL());
|
|
8263
|
+
};
|
|
8264
|
+
img.onerror = drawText;
|
|
8265
|
+
img.src = image;
|
|
8266
|
+
} else {
|
|
8267
|
+
drawText();
|
|
8268
|
+
}
|
|
8269
|
+
return () => {
|
|
8270
|
+
cancelled = true;
|
|
8271
|
+
};
|
|
8272
|
+
}, [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]);
|
|
8273
|
+
return url;
|
|
8274
|
+
}
|
|
8275
|
+
var Watermark = ({
|
|
8276
|
+
text: textProp,
|
|
8277
|
+
image,
|
|
8278
|
+
width = 180,
|
|
8279
|
+
height = 100,
|
|
8280
|
+
gapX = 16,
|
|
8281
|
+
gapY = 16,
|
|
8282
|
+
rotate: rotateProp,
|
|
8283
|
+
fontSize: fontSizeProp,
|
|
8284
|
+
fontFamily = "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial",
|
|
8285
|
+
fontWeight: fontWeightProp,
|
|
8286
|
+
fontStyle: fontStyleProp,
|
|
8287
|
+
color: colorProp,
|
|
8288
|
+
gradient,
|
|
8289
|
+
opacity = 1,
|
|
8290
|
+
offsetLeft = 0,
|
|
8291
|
+
offsetTop = 0,
|
|
8292
|
+
zIndex = 40,
|
|
8293
|
+
fullPage = false,
|
|
8294
|
+
preset,
|
|
8295
|
+
pattern = "diagonal",
|
|
8296
|
+
interactive = false,
|
|
8297
|
+
animate = false,
|
|
8298
|
+
overlayClassName,
|
|
8299
|
+
className,
|
|
8300
|
+
style,
|
|
8301
|
+
children,
|
|
8302
|
+
...rest
|
|
8303
|
+
}) => {
|
|
8304
|
+
const [visible, setVisible] = React32.useState(true);
|
|
8305
|
+
const presetConfig = preset ? PRESETS2[preset] : null;
|
|
8306
|
+
const text = textProp ?? presetConfig?.text;
|
|
8307
|
+
const color = colorProp ?? presetConfig?.color ?? "rgba(0,0,0,0.15)";
|
|
8308
|
+
const rotate = rotateProp ?? presetConfig?.rotate ?? -22;
|
|
8309
|
+
const fontSize = fontSizeProp ?? presetConfig?.fontSize ?? 14;
|
|
8310
|
+
const fontWeight = fontWeightProp ?? presetConfig?.fontWeight ?? "normal";
|
|
8311
|
+
const fontStyle = fontStyleProp ?? "normal";
|
|
8312
|
+
const dataURL = useWatermarkDataURL({
|
|
8313
|
+
text,
|
|
8314
|
+
image,
|
|
8315
|
+
width,
|
|
8316
|
+
height,
|
|
8317
|
+
gapX,
|
|
8318
|
+
gapY,
|
|
8319
|
+
rotate,
|
|
8320
|
+
fontSize,
|
|
8321
|
+
fontFamily,
|
|
8322
|
+
fontWeight,
|
|
8323
|
+
fontStyle,
|
|
8324
|
+
color,
|
|
8325
|
+
gradient,
|
|
8326
|
+
pattern
|
|
8327
|
+
});
|
|
8328
|
+
const overlayStyle = {
|
|
8329
|
+
position: fullPage ? "fixed" : "absolute",
|
|
8330
|
+
top: 0,
|
|
8331
|
+
left: 0,
|
|
8332
|
+
zIndex,
|
|
8333
|
+
opacity: visible ? opacity : 0,
|
|
8334
|
+
backgroundRepeat: "repeat",
|
|
8335
|
+
backgroundPosition: `${offsetLeft}px ${offsetTop}px`,
|
|
8336
|
+
transition: animate ? "opacity 0.3s ease" : void 0
|
|
8337
|
+
};
|
|
8338
|
+
if (fullPage) {
|
|
8339
|
+
overlayStyle.right = 0;
|
|
8340
|
+
overlayStyle.bottom = 0;
|
|
8341
|
+
} else {
|
|
8342
|
+
overlayStyle.width = "100%";
|
|
8343
|
+
overlayStyle.height = "100%";
|
|
8344
|
+
}
|
|
8345
|
+
if (dataURL) overlayStyle.backgroundImage = `url(${dataURL})`;
|
|
8346
|
+
const overlay = /* @__PURE__ */ jsx40(
|
|
8347
|
+
"div",
|
|
8348
|
+
{
|
|
8349
|
+
"aria-hidden": true,
|
|
8350
|
+
className: cn("pointer-events-none", overlayClassName),
|
|
8351
|
+
style: overlayStyle,
|
|
8352
|
+
onClick: interactive ? () => setVisible(!visible) : void 0
|
|
8353
|
+
}
|
|
8354
|
+
);
|
|
8355
|
+
if (fullPage) {
|
|
8356
|
+
return /* @__PURE__ */ jsxs35(Fragment13, { children: [
|
|
8357
|
+
children,
|
|
8358
|
+
typeof window !== "undefined" ? createPortal9(overlay, document.body) : null
|
|
8359
|
+
] });
|
|
8360
|
+
}
|
|
8361
|
+
return /* @__PURE__ */ jsxs35("div", { className: cn("relative", className), style, ...rest, children: [
|
|
8362
|
+
children,
|
|
8363
|
+
overlay
|
|
8364
|
+
] });
|
|
8365
|
+
};
|
|
8366
|
+
var Watermark_default = Watermark;
|
|
8367
|
+
|
|
8368
|
+
// ../../components/ui/Timeline.tsx
|
|
8369
|
+
import * as React33 from "react";
|
|
8370
|
+
import { ChevronDown as ChevronDown4 } from "lucide-react";
|
|
8371
|
+
import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
8372
|
+
var SIZE_STYLE = {
|
|
8373
|
+
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" },
|
|
8374
|
+
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" },
|
|
8375
|
+
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" },
|
|
8376
|
+
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" }
|
|
8377
|
+
};
|
|
8378
|
+
var STATUS_COLOR = {
|
|
8379
|
+
default: "bg-muted/60",
|
|
8380
|
+
primary: "bg-primary",
|
|
8381
|
+
success: "bg-green-500",
|
|
8382
|
+
warning: "bg-yellow-500",
|
|
8383
|
+
error: "bg-red-500",
|
|
8384
|
+
info: "bg-blue-500"
|
|
8385
|
+
};
|
|
8386
|
+
var TimelineContext = React33.createContext(null);
|
|
8387
|
+
var LINE_STYLE_MAP = {
|
|
8388
|
+
solid: "border-solid",
|
|
8389
|
+
dashed: "border-dashed",
|
|
8390
|
+
dotted: "border-dotted"
|
|
8391
|
+
};
|
|
8392
|
+
var Marker = ({ index, last, size, color, status = "default", lineColor, lineStyle, active, dot, icon: Icon, showLine }) => {
|
|
8393
|
+
const sz = SIZE_STYLE[size];
|
|
8394
|
+
const dotColor = color ? `background:${color}` : void 0;
|
|
8395
|
+
const cls = color ? void 0 : STATUS_COLOR[status];
|
|
8396
|
+
return /* @__PURE__ */ jsxs36("div", { className: "flex flex-col items-center", children: [
|
|
8397
|
+
dot ? /* @__PURE__ */ jsx41("div", { className: "flex items-center justify-center", children: dot }) : Icon ? /* @__PURE__ */ jsx41(
|
|
8398
|
+
"div",
|
|
8399
|
+
{
|
|
8400
|
+
className: cn("rounded-full ring-2 ring-background flex items-center justify-center", sz.iconDot, cls, active && "ring-primary/40 ring-4"),
|
|
8401
|
+
style: dotColor ? { background: color } : void 0,
|
|
8402
|
+
children: /* @__PURE__ */ jsx41(Icon, { className: cn("text-white", sz.icon) })
|
|
8403
|
+
}
|
|
8404
|
+
) : /* @__PURE__ */ jsx41(
|
|
8405
|
+
"div",
|
|
8406
|
+
{
|
|
8407
|
+
className: cn("rounded-full ring-2 ring-background", sz.dot, cls, active && "ring-primary/40 ring-4 scale-125"),
|
|
8408
|
+
style: dotColor ? { background: color } : void 0
|
|
8409
|
+
}
|
|
8410
|
+
),
|
|
8411
|
+
!last && showLine && /* @__PURE__ */ jsx41(
|
|
8412
|
+
"div",
|
|
8413
|
+
{
|
|
8414
|
+
className: cn("flex-1 border-l-2", LINE_STYLE_MAP[lineStyle]),
|
|
8415
|
+
style: { borderColor: lineColor || "hsl(var(--border))" }
|
|
8416
|
+
}
|
|
8417
|
+
)
|
|
8418
|
+
] });
|
|
8419
|
+
};
|
|
8420
|
+
var TimelineRoot = React33.forwardRef(
|
|
8421
|
+
({
|
|
8422
|
+
align = "left",
|
|
8423
|
+
variant = "default",
|
|
8424
|
+
size = "md",
|
|
8425
|
+
mode = "vertical",
|
|
8426
|
+
lineColor,
|
|
8427
|
+
lineStyle = "solid",
|
|
8428
|
+
items,
|
|
8429
|
+
itemClassName,
|
|
8430
|
+
animate = false,
|
|
8431
|
+
dense = false,
|
|
8432
|
+
showLine = true,
|
|
8433
|
+
className,
|
|
8434
|
+
children,
|
|
8435
|
+
...rest
|
|
8436
|
+
}, ref) => {
|
|
8437
|
+
const content = items ? items.map((it, i) => /* @__PURE__ */ jsx41(TimelineItem, { ...it, className: cn(itemClassName, it.className), "data-index": i, "data-last": i === (items?.length ?? 0) - 1 }, i)) : children;
|
|
8438
|
+
return /* @__PURE__ */ jsx41(TimelineContext.Provider, { value: { align, variant, size, mode, lineColor, lineStyle, itemClassName, animate, dense, showLine }, children: /* @__PURE__ */ jsx41(
|
|
8439
|
+
"div",
|
|
8440
|
+
{
|
|
8441
|
+
ref,
|
|
8442
|
+
className: cn(
|
|
8443
|
+
"relative",
|
|
8444
|
+
mode === "horizontal" && "flex gap-4 overflow-x-auto",
|
|
8445
|
+
mode === "vertical" && "space-y-0",
|
|
8446
|
+
className
|
|
8447
|
+
),
|
|
8448
|
+
...rest,
|
|
8449
|
+
children: mode === "vertical" ? /* @__PURE__ */ jsx41("div", { className: "space-y-0", children: content }) : content
|
|
8450
|
+
}
|
|
8451
|
+
) });
|
|
8452
|
+
}
|
|
8453
|
+
);
|
|
8454
|
+
TimelineRoot.displayName = "Timeline";
|
|
8455
|
+
var TimelineItem = React33.forwardRef(
|
|
8456
|
+
({
|
|
8457
|
+
title,
|
|
8458
|
+
description,
|
|
8459
|
+
time,
|
|
8460
|
+
icon: Icon,
|
|
8461
|
+
status = "default",
|
|
8462
|
+
color,
|
|
8463
|
+
active = false,
|
|
8464
|
+
dot,
|
|
8465
|
+
collapsible = false,
|
|
8466
|
+
expanded: controlledExpanded,
|
|
8467
|
+
onExpandChange,
|
|
8468
|
+
expandContent,
|
|
8469
|
+
badge,
|
|
8470
|
+
className,
|
|
8471
|
+
children,
|
|
8472
|
+
...rest
|
|
8473
|
+
}, ref) => {
|
|
8474
|
+
const ctx = React33.useContext(TimelineContext);
|
|
8475
|
+
const idx = rest["data-index"];
|
|
8476
|
+
const isLast = Boolean(rest["data-last"]);
|
|
8477
|
+
const sz = SIZE_STYLE[ctx.size];
|
|
8478
|
+
const [internalExpanded, setInternalExpanded] = React33.useState(false);
|
|
8479
|
+
const isExpanded = controlledExpanded !== void 0 ? controlledExpanded : internalExpanded;
|
|
8480
|
+
const toggleExpanded = () => {
|
|
8481
|
+
const newExpanded = !isExpanded;
|
|
8482
|
+
if (onExpandChange) {
|
|
8483
|
+
onExpandChange(newExpanded);
|
|
8484
|
+
} else {
|
|
8485
|
+
setInternalExpanded(newExpanded);
|
|
8486
|
+
}
|
|
8487
|
+
};
|
|
8488
|
+
const padding = ctx.dense ? sz.densePadY : sz.padY;
|
|
8489
|
+
const variantClasses = {
|
|
8490
|
+
default: "",
|
|
8491
|
+
outlined: "rounded-lg border border-border bg-card shadow-sm px-4 py-3",
|
|
8492
|
+
card: "rounded-xl border border-border bg-card shadow-md px-5 py-4",
|
|
8493
|
+
minimal: "border-l-2 pl-4 py-2",
|
|
8494
|
+
modern: "rounded-lg bg-gradient-to-r from-card to-muted/20 border border-border/50 px-5 py-4 backdrop-blur-sm",
|
|
8495
|
+
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"
|
|
8496
|
+
};
|
|
8497
|
+
const contentBox = /* @__PURE__ */ jsxs36("div", { className: cn("min-w-0 flex-1", variantClasses[ctx.variant]), children: [
|
|
8498
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-start justify-between gap-2", children: [
|
|
8499
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex-1 min-w-0", children: [
|
|
8500
|
+
title && /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2", children: [
|
|
8501
|
+
/* @__PURE__ */ jsx41("div", { className: cn("font-semibold text-foreground", sz.title), children: title }),
|
|
8502
|
+
badge && /* @__PURE__ */ jsx41("span", { className: "px-2 py-0.5 rounded-full text-[10px] font-medium bg-primary/10 text-primary", children: badge })
|
|
8503
|
+
] }),
|
|
8504
|
+
description && /* @__PURE__ */ jsx41("div", { className: cn("text-muted-foreground mt-1", sz.desc), children: description }),
|
|
8505
|
+
children && /* @__PURE__ */ jsx41("div", { className: "mt-2", children })
|
|
8506
|
+
] }),
|
|
8507
|
+
collapsible && /* @__PURE__ */ jsx41(
|
|
8508
|
+
"button",
|
|
8509
|
+
{
|
|
8510
|
+
type: "button",
|
|
8511
|
+
onClick: toggleExpanded,
|
|
8512
|
+
className: cn("text-muted-foreground hover:text-foreground transition-transform p-1", isExpanded && "rotate-180"),
|
|
8513
|
+
children: /* @__PURE__ */ jsx41(ChevronDown4, { className: "h-4 w-4" })
|
|
8514
|
+
}
|
|
8515
|
+
)
|
|
8516
|
+
] }),
|
|
8517
|
+
time && /* @__PURE__ */ jsx41("div", { className: cn("mt-2 text-muted-foreground flex items-center gap-1", sz.time), children: time }),
|
|
8518
|
+
collapsible && isExpanded && expandContent && /* @__PURE__ */ jsx41("div", { className: "mt-3 pt-3 border-t border-border/50 text-sm", children: expandContent })
|
|
8519
|
+
] });
|
|
8520
|
+
const markerWidth = Icon || dot ? "w-auto" : "w-6";
|
|
8521
|
+
const leftSide = /* @__PURE__ */ jsxs36("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: [
|
|
8522
|
+
/* @__PURE__ */ jsx41("div", { className: cn("flex-shrink-0 flex items-stretch", markerWidth), children: /* @__PURE__ */ jsx41(Marker, { index: idx ?? 0, last: isLast, size: ctx.size, color, status, lineColor: ctx.lineColor, lineStyle: ctx.lineStyle, active, dot, icon: Icon, showLine: ctx.showLine }) }),
|
|
8523
|
+
/* @__PURE__ */ jsx41("div", { className: "flex-1", children: contentBox })
|
|
8524
|
+
] });
|
|
8525
|
+
const rightSide = /* @__PURE__ */ jsxs36("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: [
|
|
8526
|
+
/* @__PURE__ */ jsx41("div", { className: "flex-1 flex justify-end", children: contentBox }),
|
|
8527
|
+
/* @__PURE__ */ jsx41("div", { className: cn("flex-shrink-0 flex items-stretch", markerWidth), children: /* @__PURE__ */ jsx41(Marker, { index: idx ?? 0, last: isLast, size: ctx.size, color, status, lineColor: ctx.lineColor, lineStyle: ctx.lineStyle, active, dot, icon: Icon, showLine: ctx.showLine }) })
|
|
8528
|
+
] });
|
|
8529
|
+
const horizontalItem = /* @__PURE__ */ jsxs36(
|
|
8530
|
+
"div",
|
|
8531
|
+
{
|
|
8532
|
+
className: cn(
|
|
8533
|
+
"flex flex-col items-center gap-2 min-w-[200px]",
|
|
8534
|
+
ctx.animate && "animate-in fade-in-50 zoom-in-95 duration-500"
|
|
8535
|
+
),
|
|
8536
|
+
style: { animationDelay: ctx.animate ? `${(idx ?? 0) * 100}ms` : void 0 },
|
|
8537
|
+
children: [
|
|
8538
|
+
/* @__PURE__ */ jsx41(Marker, { index: idx ?? 0, last: isLast, size: ctx.size, color, status, lineColor: ctx.lineColor, lineStyle: ctx.lineStyle, active, dot, icon: Icon, showLine: false }),
|
|
8539
|
+
!isLast && ctx.showLine && /* @__PURE__ */ jsx41("div", { className: cn("h-px w-full border-t-2", LINE_STYLE_MAP[ctx.lineStyle]), style: { borderColor: ctx.lineColor || "hsl(var(--border))" } }),
|
|
8540
|
+
contentBox
|
|
8541
|
+
]
|
|
8542
|
+
}
|
|
8543
|
+
);
|
|
8544
|
+
if (ctx.mode === "horizontal") {
|
|
8545
|
+
return /* @__PURE__ */ jsx41("div", { ref, className: cn("relative", className), ...rest, children: horizontalItem });
|
|
8546
|
+
}
|
|
8547
|
+
let row = leftSide;
|
|
8548
|
+
if (ctx.align === "right") row = rightSide;
|
|
8549
|
+
if (ctx.align === "alternate") row = (idx ?? 0) % 2 === 0 ? leftSide : rightSide;
|
|
8550
|
+
return /* @__PURE__ */ jsx41("div", { ref, className: cn("relative", className), ...rest, children: row });
|
|
8551
|
+
}
|
|
8552
|
+
);
|
|
8553
|
+
TimelineItem.displayName = "Timeline.Item";
|
|
8554
|
+
var Timeline = Object.assign(TimelineRoot, { Item: TimelineItem });
|
|
8555
|
+
var Timeline_default = Timeline;
|
|
8556
|
+
|
|
8557
|
+
// ../../components/ui/ColorPicker.tsx
|
|
8558
|
+
import * as React34 from "react";
|
|
8559
|
+
import { Pipette, X as X10, Copy, Check as Check8, Palette, History } from "lucide-react";
|
|
8560
|
+
import { jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
8561
|
+
var clamp = (n, min, max) => Math.max(min, Math.min(max, n));
|
|
8562
|
+
function hexToRgb(hex) {
|
|
8563
|
+
const str = hex.replace(/^#/, "").trim();
|
|
8564
|
+
if (str.length === 3) {
|
|
8565
|
+
const r = parseInt(str[0] + str[0], 16);
|
|
8566
|
+
const g = parseInt(str[1] + str[1], 16);
|
|
8567
|
+
const b = parseInt(str[2] + str[2], 16);
|
|
8568
|
+
return { r, g, b };
|
|
8569
|
+
}
|
|
8570
|
+
if (str.length === 6) {
|
|
8571
|
+
const r = parseInt(str.slice(0, 2), 16);
|
|
8572
|
+
const g = parseInt(str.slice(2, 4), 16);
|
|
8573
|
+
const b = parseInt(str.slice(4, 6), 16);
|
|
8574
|
+
return { r, g, b };
|
|
8575
|
+
}
|
|
8576
|
+
return null;
|
|
8577
|
+
}
|
|
8578
|
+
function rgbToHex(r, g, b) {
|
|
8579
|
+
return `#${[r, g, b].map((v) => clamp(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
|
|
8580
|
+
}
|
|
8581
|
+
function rgbToHsl(r, g, b) {
|
|
8582
|
+
r /= 255;
|
|
8583
|
+
g /= 255;
|
|
8584
|
+
b /= 255;
|
|
8585
|
+
const max = Math.max(r, g, b);
|
|
8586
|
+
const min = Math.min(r, g, b);
|
|
8587
|
+
let h = 0, s = 0;
|
|
8588
|
+
const l = (max + min) / 2;
|
|
8589
|
+
if (max !== min) {
|
|
8590
|
+
const d = max - min;
|
|
8591
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
8592
|
+
switch (max) {
|
|
8593
|
+
case r:
|
|
8594
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
8595
|
+
break;
|
|
8596
|
+
case g:
|
|
8597
|
+
h = ((b - r) / d + 2) / 6;
|
|
8598
|
+
break;
|
|
8599
|
+
case b:
|
|
8600
|
+
h = ((r - g) / d + 4) / 6;
|
|
8601
|
+
break;
|
|
8602
|
+
}
|
|
8603
|
+
}
|
|
8604
|
+
return { h: h * 360, s: s * 100, l: l * 100 };
|
|
8605
|
+
}
|
|
8606
|
+
function hslToRgb(h, s, l) {
|
|
8607
|
+
h /= 360;
|
|
8608
|
+
s /= 100;
|
|
8609
|
+
l /= 100;
|
|
8610
|
+
let r, g, b;
|
|
8611
|
+
if (s === 0) {
|
|
8612
|
+
r = g = b = l;
|
|
8613
|
+
} else {
|
|
8614
|
+
const hue2rgb = (p2, q2, t) => {
|
|
8615
|
+
if (t < 0) t += 1;
|
|
8616
|
+
if (t > 1) t -= 1;
|
|
8617
|
+
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
8618
|
+
if (t < 1 / 2) return q2;
|
|
8619
|
+
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
8620
|
+
return p2;
|
|
8621
|
+
};
|
|
8622
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
8623
|
+
const p = 2 * l - q;
|
|
8624
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
8625
|
+
g = hue2rgb(p, q, h);
|
|
8626
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
8627
|
+
}
|
|
8628
|
+
return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };
|
|
8629
|
+
}
|
|
8630
|
+
function parseAnyColor(input) {
|
|
8631
|
+
if (!input) return null;
|
|
8632
|
+
const s = input.trim();
|
|
8633
|
+
if (s.startsWith("#")) {
|
|
8634
|
+
const rgb = hexToRgb(s);
|
|
8635
|
+
if (!rgb) return null;
|
|
8636
|
+
return { ...rgb, a: 1 };
|
|
8637
|
+
}
|
|
8638
|
+
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);
|
|
8639
|
+
if (rgbaMatch) {
|
|
8640
|
+
const r = clamp(parseInt(rgbaMatch[1], 10), 0, 255);
|
|
8641
|
+
const g = clamp(parseInt(rgbaMatch[2], 10), 0, 255);
|
|
8642
|
+
const b = clamp(parseInt(rgbaMatch[3], 10), 0, 255);
|
|
8643
|
+
const a = rgbaMatch[4] != null ? clamp(parseFloat(rgbaMatch[4]), 0, 1) : 1;
|
|
8644
|
+
return { r, g, b, a };
|
|
8645
|
+
}
|
|
8646
|
+
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);
|
|
8647
|
+
if (hslaMatch) {
|
|
8648
|
+
const h = parseFloat(hslaMatch[1]);
|
|
8649
|
+
const sl = parseFloat(hslaMatch[2]);
|
|
8650
|
+
const l = parseFloat(hslaMatch[3]);
|
|
8651
|
+
const a = hslaMatch[4] != null ? clamp(parseFloat(hslaMatch[4]), 0, 1) : 1;
|
|
8652
|
+
const rgb = hslToRgb(h, sl, l);
|
|
8653
|
+
return { ...rgb, a };
|
|
8654
|
+
}
|
|
8655
|
+
return null;
|
|
8656
|
+
}
|
|
8657
|
+
function formatOutput({ r, g, b, a }, withAlpha, format) {
|
|
8658
|
+
if (format === "hex" && (!withAlpha || a === 1)) {
|
|
8659
|
+
return rgbToHex(r, g, b);
|
|
8660
|
+
}
|
|
8661
|
+
if (format === "hsl" || format === "hsla") {
|
|
8662
|
+
const hsl = rgbToHsl(r, g, b);
|
|
8663
|
+
if (format === "hsla" || withAlpha) {
|
|
8664
|
+
return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp(a, 0, 1)})`;
|
|
8665
|
+
}
|
|
8666
|
+
return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
|
|
8667
|
+
}
|
|
8668
|
+
if (withAlpha || a !== 1) {
|
|
8669
|
+
return `rgba(${clamp(r, 0, 255)}, ${clamp(g, 0, 255)}, ${clamp(b, 0, 255)}, ${clamp(a, 0, 1)})`;
|
|
8670
|
+
}
|
|
8671
|
+
return rgbToHex(r, g, b);
|
|
8672
|
+
}
|
|
8673
|
+
function getColorHarmony(rgba) {
|
|
8674
|
+
const hsl = rgbToHsl(rgba.r, rgba.g, rgba.b);
|
|
8675
|
+
const compH = (hsl.h + 180) % 360;
|
|
8676
|
+
const compRgb = hslToRgb(compH, hsl.s, hsl.l);
|
|
8677
|
+
const tri1H = (hsl.h + 120) % 360;
|
|
8678
|
+
const tri2H = (hsl.h + 240) % 360;
|
|
8679
|
+
const tri1Rgb = hslToRgb(tri1H, hsl.s, hsl.l);
|
|
8680
|
+
const tri2Rgb = hslToRgb(tri2H, hsl.s, hsl.l);
|
|
8681
|
+
const ana1H = (hsl.h + 30) % 360;
|
|
8682
|
+
const ana2H = (hsl.h - 30 + 360) % 360;
|
|
8683
|
+
const ana1Rgb = hslToRgb(ana1H, hsl.s, hsl.l);
|
|
8684
|
+
const ana2Rgb = hslToRgb(ana2H, hsl.s, hsl.l);
|
|
8685
|
+
return {
|
|
8686
|
+
complementary: rgbToHex(compRgb.r, compRgb.g, compRgb.b),
|
|
8687
|
+
triadic: [rgbToHex(tri1Rgb.r, tri1Rgb.g, tri1Rgb.b), rgbToHex(tri2Rgb.r, tri2Rgb.g, tri2Rgb.b)],
|
|
8688
|
+
analogous: [rgbToHex(ana1Rgb.r, ana1Rgb.g, ana1Rgb.b), rgbToHex(ana2Rgb.r, ana2Rgb.g, ana2Rgb.b)]
|
|
8689
|
+
};
|
|
8690
|
+
}
|
|
8691
|
+
var DEFAULT_PRESETS = [
|
|
8692
|
+
"#000000",
|
|
8693
|
+
"#ffffff",
|
|
8694
|
+
"#f87171",
|
|
8695
|
+
"#fb923c",
|
|
8696
|
+
"#fbbf24",
|
|
8697
|
+
"#34d399",
|
|
8698
|
+
"#60a5fa",
|
|
8699
|
+
"#a78bfa",
|
|
8700
|
+
"#f472b6",
|
|
8701
|
+
"#111827",
|
|
8702
|
+
"#4b5563",
|
|
8703
|
+
"#9ca3af",
|
|
8704
|
+
"#d1d5db",
|
|
8705
|
+
"#e5e7eb",
|
|
8706
|
+
"#f3f4f6"
|
|
8707
|
+
];
|
|
8708
|
+
var Swatch = ({
|
|
8709
|
+
color,
|
|
8710
|
+
onClick,
|
|
8711
|
+
ariaLabel,
|
|
8712
|
+
size = "md"
|
|
8713
|
+
}) => {
|
|
8714
|
+
const sizeClasses2 = {
|
|
8715
|
+
sm: "h-5 w-5",
|
|
8716
|
+
md: "h-6 w-6",
|
|
8717
|
+
lg: "h-8 w-8"
|
|
8718
|
+
};
|
|
8719
|
+
return /* @__PURE__ */ jsx42(
|
|
8720
|
+
"button",
|
|
8721
|
+
{
|
|
8722
|
+
type: "button",
|
|
8723
|
+
className: cn(
|
|
8724
|
+
sizeClasses2[size],
|
|
8725
|
+
"rounded-md border border-border shadow-sm hover:scale-110 transition-transform",
|
|
8726
|
+
onClick && "cursor-pointer"
|
|
8727
|
+
),
|
|
8728
|
+
style: { backgroundColor: color },
|
|
8729
|
+
onClick,
|
|
8730
|
+
"aria-label": ariaLabel
|
|
8731
|
+
}
|
|
8732
|
+
);
|
|
8733
|
+
};
|
|
8734
|
+
function ColorPicker({
|
|
8735
|
+
value,
|
|
8736
|
+
defaultValue = "#4f46e5",
|
|
8737
|
+
onChange,
|
|
8738
|
+
disabled = false,
|
|
8739
|
+
withAlpha = false,
|
|
8740
|
+
format = "hex",
|
|
8741
|
+
presets,
|
|
8742
|
+
className,
|
|
8743
|
+
triggerClassName,
|
|
8744
|
+
contentClassName,
|
|
8745
|
+
clearable = false,
|
|
8746
|
+
copyable = true,
|
|
8747
|
+
size = "md",
|
|
8748
|
+
variant = "default",
|
|
8749
|
+
showRecent = false,
|
|
8750
|
+
showHarmony = false,
|
|
8751
|
+
maxRecent = 8,
|
|
8752
|
+
...rest
|
|
8753
|
+
}) {
|
|
8754
|
+
const isControlled = value !== void 0;
|
|
8755
|
+
const initial = parseAnyColor(isControlled ? value : defaultValue) || { r: 79, g: 70, b: 229, a: 1 };
|
|
8756
|
+
const [rgba, setRgba] = React34.useState(initial);
|
|
8757
|
+
const [open, setOpen] = React34.useState(false);
|
|
8758
|
+
const [text, setText] = React34.useState(() => formatOutput(initial, withAlpha, format));
|
|
8759
|
+
const [copied, setCopied] = React34.useState(false);
|
|
8760
|
+
const [recentColors, setRecentColors] = React34.useState([]);
|
|
8761
|
+
React34.useEffect(() => {
|
|
8762
|
+
if (isControlled) {
|
|
8763
|
+
const parsed = parseAnyColor(value);
|
|
8764
|
+
if (parsed) {
|
|
8765
|
+
setRgba(parsed);
|
|
8766
|
+
setText(formatOutput(parsed, withAlpha, format));
|
|
8767
|
+
}
|
|
8768
|
+
}
|
|
8769
|
+
}, [value]);
|
|
8770
|
+
const emit = (next) => {
|
|
8771
|
+
const out = formatOutput(next, withAlpha, format);
|
|
8772
|
+
if (!isControlled) setText(out);
|
|
8773
|
+
onChange?.(out);
|
|
8774
|
+
if (showRecent) {
|
|
8775
|
+
const hexColor = rgbToHex(next.r, next.g, next.b);
|
|
8776
|
+
setRecentColors((prev) => {
|
|
8777
|
+
const filtered = prev.filter((c) => c !== hexColor);
|
|
8778
|
+
return [hexColor, ...filtered].slice(0, maxRecent);
|
|
8779
|
+
});
|
|
8780
|
+
}
|
|
8781
|
+
};
|
|
8782
|
+
const copyToClipboard = async () => {
|
|
8783
|
+
try {
|
|
8784
|
+
await navigator.clipboard.writeText(text);
|
|
8785
|
+
setCopied(true);
|
|
8786
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
8787
|
+
} catch (err) {
|
|
8788
|
+
console.error("Failed to copy:", err);
|
|
8789
|
+
}
|
|
8790
|
+
};
|
|
8791
|
+
const handleHexChange = (raw) => {
|
|
8792
|
+
setText(raw);
|
|
8793
|
+
const parsed = parseAnyColor(raw);
|
|
8794
|
+
if (parsed) {
|
|
8795
|
+
setRgba((prev) => ({ ...parsed, a: withAlpha ? parsed.a : 1 }));
|
|
8796
|
+
emit({ ...parsed, a: withAlpha ? parsed.a : 1 });
|
|
8797
|
+
}
|
|
8798
|
+
};
|
|
8799
|
+
const handleNativeChange = (e) => {
|
|
8800
|
+
const hex = e.target.value || "#000000";
|
|
8801
|
+
const rgb = hexToRgb(hex) || { r: 0, g: 0, b: 0 };
|
|
8802
|
+
const next = { ...rgba, ...rgb };
|
|
8803
|
+
setRgba(next);
|
|
8804
|
+
emit(next);
|
|
8805
|
+
};
|
|
8806
|
+
const setAlpha = (aPct) => {
|
|
8807
|
+
const a = clamp(aPct / 100, 0, 1);
|
|
8808
|
+
const next = { ...rgba, a };
|
|
8809
|
+
setRgba(next);
|
|
8810
|
+
emit(next);
|
|
8811
|
+
};
|
|
8812
|
+
const tryEyedropper = async () => {
|
|
8813
|
+
if (typeof window !== "undefined" && window.EyeDropper) {
|
|
8814
|
+
const eye = new window.EyeDropper();
|
|
8815
|
+
try {
|
|
8816
|
+
const res = await eye.open();
|
|
8817
|
+
const rgb = hexToRgb(res.sRGBHex);
|
|
8818
|
+
if (rgb) {
|
|
8819
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
8820
|
+
setRgba(next);
|
|
8821
|
+
emit(next);
|
|
8822
|
+
}
|
|
8823
|
+
} catch {
|
|
8824
|
+
}
|
|
8825
|
+
}
|
|
8826
|
+
};
|
|
8827
|
+
const clear = () => {
|
|
8828
|
+
setText("");
|
|
8829
|
+
const next = { r: 0, g: 0, b: 0, a: 0 };
|
|
8830
|
+
setRgba(next);
|
|
8831
|
+
onChange?.("");
|
|
8832
|
+
};
|
|
8833
|
+
const swatches = presets && presets.length ? presets : DEFAULT_PRESETS;
|
|
8834
|
+
const hexForInput = rgbToHex(rgba.r, rgba.g, rgba.b);
|
|
8835
|
+
const alphaPct = Math.round(rgba.a * 100);
|
|
8836
|
+
const harmony = showHarmony ? getColorHarmony(rgba) : null;
|
|
8837
|
+
const sizeClasses2 = {
|
|
8838
|
+
sm: "h-8 text-xs",
|
|
8839
|
+
md: "h-10 text-sm",
|
|
8840
|
+
lg: "h-12 text-base"
|
|
8841
|
+
};
|
|
8842
|
+
const swatchSize = size === "sm" ? "sm" : size === "lg" ? "lg" : "md";
|
|
8843
|
+
const trigger = /* @__PURE__ */ jsxs37(
|
|
8844
|
+
"button",
|
|
8845
|
+
{
|
|
8846
|
+
type: "button",
|
|
8847
|
+
disabled,
|
|
8848
|
+
className: cn(
|
|
8849
|
+
"w-full px-3 rounded-lg border border-input bg-background flex items-center justify-between",
|
|
8850
|
+
sizeClasses2[size],
|
|
8851
|
+
"hover:border-accent-foreground/30 transition-colors",
|
|
8852
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
8853
|
+
triggerClassName
|
|
8854
|
+
),
|
|
8855
|
+
"aria-label": "Open color picker",
|
|
8856
|
+
children: [
|
|
8857
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
8858
|
+
/* @__PURE__ */ jsx42(
|
|
8859
|
+
"span",
|
|
8860
|
+
{
|
|
8861
|
+
className: cn(
|
|
8862
|
+
"rounded border border-border shadow-sm",
|
|
8863
|
+
size === "sm" ? "h-4 w-4" : size === "lg" ? "h-6 w-6" : "h-5 w-5"
|
|
8864
|
+
),
|
|
8865
|
+
style: { backgroundColor: withAlpha ? `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})` : hexForInput }
|
|
8866
|
+
}
|
|
8867
|
+
),
|
|
8868
|
+
/* @__PURE__ */ jsx42("span", { className: "font-mono text-muted-foreground", children: text })
|
|
8869
|
+
] }),
|
|
8870
|
+
/* @__PURE__ */ jsx42(Pipette, { className: cn(size === "sm" ? "w-3.5 h-3.5" : size === "lg" ? "w-5 h-5" : "w-4 h-4", "text-muted-foreground") })
|
|
8871
|
+
]
|
|
8872
|
+
}
|
|
8873
|
+
);
|
|
8874
|
+
const contentWidthByVariant = {
|
|
8875
|
+
minimal: 240,
|
|
8876
|
+
compact: 280,
|
|
8877
|
+
default: 320,
|
|
8878
|
+
full: 360
|
|
8879
|
+
};
|
|
8880
|
+
return /* @__PURE__ */ jsx42("div", { className: cn("inline-block w-full", className), ...rest, children: /* @__PURE__ */ jsx42(
|
|
8881
|
+
Popover,
|
|
8882
|
+
{
|
|
8883
|
+
trigger,
|
|
8884
|
+
open,
|
|
8885
|
+
onOpenChange: setOpen,
|
|
8886
|
+
placement: "bottom-start",
|
|
8887
|
+
matchTriggerWidth: variant === "minimal",
|
|
8888
|
+
contentWidth: contentWidthByVariant[variant],
|
|
8889
|
+
contentClassName: cn("p-3 rounded-lg border border-border bg-card shadow-lg", contentClassName),
|
|
8890
|
+
children: /* @__PURE__ */ jsxs37("div", { className: "space-y-3", children: [
|
|
8891
|
+
variant !== "minimal" && /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
8892
|
+
/* @__PURE__ */ jsx42("input", { type: "color", value: hexForInput, onChange: handleNativeChange, className: "h-9 w-9 rounded-md cursor-pointer border border-border" }),
|
|
8893
|
+
/* @__PURE__ */ jsxs37(
|
|
8894
|
+
"button",
|
|
8895
|
+
{
|
|
8896
|
+
type: "button",
|
|
8897
|
+
onClick: tryEyedropper,
|
|
8898
|
+
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"),
|
|
8899
|
+
children: [
|
|
8900
|
+
/* @__PURE__ */ jsx42(Pipette, { className: "w-3.5 h-3.5" }),
|
|
8901
|
+
variant === "full" && "Pick"
|
|
8902
|
+
]
|
|
8903
|
+
}
|
|
8904
|
+
),
|
|
8905
|
+
copyable && /* @__PURE__ */ jsxs37(
|
|
8906
|
+
"button",
|
|
8907
|
+
{
|
|
8908
|
+
type: "button",
|
|
8909
|
+
onClick: copyToClipboard,
|
|
8910
|
+
className: cn(
|
|
8911
|
+
"h-9 px-3 rounded-md border border-border text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5",
|
|
8912
|
+
copied && "bg-green-500/10 border-green-500/30"
|
|
8913
|
+
),
|
|
8914
|
+
children: [
|
|
8915
|
+
copied ? /* @__PURE__ */ jsx42(Check8, { className: "w-3.5 h-3.5 text-green-600" }) : /* @__PURE__ */ jsx42(Copy, { className: "w-3.5 h-3.5" }),
|
|
8916
|
+
variant === "full" && (copied ? "Copied!" : "Copy")
|
|
8917
|
+
]
|
|
8918
|
+
}
|
|
8919
|
+
),
|
|
8920
|
+
clearable && /* @__PURE__ */ jsxs37(
|
|
8921
|
+
"button",
|
|
8922
|
+
{
|
|
8923
|
+
type: "button",
|
|
8924
|
+
onClick: clear,
|
|
8925
|
+
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",
|
|
8926
|
+
children: [
|
|
8927
|
+
/* @__PURE__ */ jsx42(X10, { className: "w-3.5 h-3.5" }),
|
|
8928
|
+
variant === "full" && "Clear"
|
|
8929
|
+
]
|
|
8930
|
+
}
|
|
8931
|
+
)
|
|
8932
|
+
] }),
|
|
8933
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
8934
|
+
/* @__PURE__ */ jsx42(
|
|
8935
|
+
Input_default,
|
|
8936
|
+
{
|
|
8937
|
+
value: text,
|
|
8938
|
+
onChange: (e) => handleHexChange(e.target.value),
|
|
8939
|
+
placeholder: format === "hsl" || format === "hsla" ? "hsl(240, 82%, 59%)" : withAlpha || format === "rgba" ? "rgba(79,70,229,1)" : "#4f46e5",
|
|
8940
|
+
variant: "outlined",
|
|
8941
|
+
size: "sm",
|
|
8942
|
+
className: "flex-1"
|
|
8943
|
+
}
|
|
8944
|
+
),
|
|
8945
|
+
variant === "minimal" && copyable && /* @__PURE__ */ jsx42(
|
|
8946
|
+
"button",
|
|
8947
|
+
{
|
|
8948
|
+
type: "button",
|
|
8949
|
+
onClick: copyToClipboard,
|
|
8950
|
+
className: cn(
|
|
8951
|
+
"h-9 w-9 rounded-md border border-border hover:bg-accent/10 transition-colors flex items-center justify-center",
|
|
8952
|
+
copied && "bg-green-500/10 border-green-500/30"
|
|
8953
|
+
),
|
|
8954
|
+
children: copied ? /* @__PURE__ */ jsx42(Check8, { className: "w-3.5 h-3.5 text-green-600" }) : /* @__PURE__ */ jsx42(Copy, { className: "w-3.5 h-3.5" })
|
|
8955
|
+
}
|
|
8956
|
+
)
|
|
8957
|
+
] }),
|
|
8958
|
+
withAlpha && /* @__PURE__ */ jsx42("div", { className: "pt-1", children: /* @__PURE__ */ jsx42(Slider, { min: 0, max: 100, step: 1, value: alphaPct, onChange: (v) => setAlpha(v), label: "Alpha", showValue: true, formatValue: (v) => `${v}%`, size: "sm" }) }),
|
|
8959
|
+
variant !== "minimal" && /* @__PURE__ */ jsxs37("div", { children: [
|
|
8960
|
+
/* @__PURE__ */ jsxs37("div", { className: "text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1.5", children: [
|
|
8961
|
+
/* @__PURE__ */ jsx42(Palette, { className: "w-3.5 h-3.5" }),
|
|
8962
|
+
" Presets"
|
|
8963
|
+
] }),
|
|
8964
|
+
/* @__PURE__ */ jsx42("div", { className: "grid grid-cols-8 gap-2", children: swatches.map((c) => /* @__PURE__ */ jsx42(
|
|
8965
|
+
Swatch,
|
|
8966
|
+
{
|
|
8967
|
+
color: c,
|
|
8968
|
+
ariaLabel: c,
|
|
8969
|
+
size: swatchSize,
|
|
8970
|
+
onClick: () => {
|
|
8971
|
+
const rgb = hexToRgb(c);
|
|
8972
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
8973
|
+
setRgba(next);
|
|
8974
|
+
emit(next);
|
|
8975
|
+
}
|
|
8976
|
+
},
|
|
8977
|
+
c
|
|
8978
|
+
)) })
|
|
8979
|
+
] }),
|
|
8980
|
+
showRecent && recentColors.length > 0 && /* @__PURE__ */ jsxs37("div", { children: [
|
|
8981
|
+
/* @__PURE__ */ jsxs37("div", { className: "text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1.5", children: [
|
|
8982
|
+
/* @__PURE__ */ jsx42(History, { className: "w-3.5 h-3.5" }),
|
|
8983
|
+
" Recent"
|
|
8984
|
+
] }),
|
|
8985
|
+
/* @__PURE__ */ jsx42("div", { className: "flex gap-2 flex-wrap", children: recentColors.map((c, i) => /* @__PURE__ */ jsx42(
|
|
8986
|
+
Swatch,
|
|
8987
|
+
{
|
|
8988
|
+
color: c,
|
|
8989
|
+
ariaLabel: c,
|
|
8990
|
+
size: swatchSize,
|
|
8991
|
+
onClick: () => {
|
|
8992
|
+
const rgb = hexToRgb(c);
|
|
8993
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
8994
|
+
setRgba(next);
|
|
8995
|
+
emit(next);
|
|
8996
|
+
}
|
|
8997
|
+
},
|
|
8998
|
+
`${c}-${i}`
|
|
8999
|
+
)) })
|
|
9000
|
+
] }),
|
|
9001
|
+
showHarmony && harmony && variant !== "minimal" && /* @__PURE__ */ jsxs37("div", { children: [
|
|
9002
|
+
/* @__PURE__ */ jsx42("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Harmony" }),
|
|
9003
|
+
/* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
|
|
9004
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
9005
|
+
/* @__PURE__ */ jsx42("span", { className: "text-xs text-muted-foreground w-24", children: "Complementary" }),
|
|
9006
|
+
/* @__PURE__ */ jsx42(
|
|
9007
|
+
Swatch,
|
|
9008
|
+
{
|
|
9009
|
+
color: harmony.complementary,
|
|
9010
|
+
ariaLabel: "Complementary",
|
|
9011
|
+
size: swatchSize,
|
|
9012
|
+
onClick: () => {
|
|
9013
|
+
const rgb = hexToRgb(harmony.complementary);
|
|
9014
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9015
|
+
setRgba(next);
|
|
9016
|
+
emit(next);
|
|
9017
|
+
}
|
|
9018
|
+
}
|
|
9019
|
+
),
|
|
9020
|
+
/* @__PURE__ */ jsx42("span", { className: "text-xs font-mono text-muted-foreground", children: harmony.complementary })
|
|
9021
|
+
] }),
|
|
9022
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
9023
|
+
/* @__PURE__ */ jsx42("span", { className: "text-xs text-muted-foreground w-24", children: "Triadic" }),
|
|
9024
|
+
/* @__PURE__ */ jsx42("div", { className: "flex gap-2", children: harmony.triadic.map((c) => /* @__PURE__ */ jsx42(
|
|
9025
|
+
Swatch,
|
|
9026
|
+
{
|
|
9027
|
+
color: c,
|
|
9028
|
+
ariaLabel: c,
|
|
9029
|
+
size: swatchSize,
|
|
9030
|
+
onClick: () => {
|
|
9031
|
+
const rgb = hexToRgb(c);
|
|
9032
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9033
|
+
setRgba(next);
|
|
9034
|
+
emit(next);
|
|
9035
|
+
}
|
|
9036
|
+
},
|
|
9037
|
+
c
|
|
9038
|
+
)) })
|
|
9039
|
+
] }),
|
|
9040
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
9041
|
+
/* @__PURE__ */ jsx42("span", { className: "text-xs text-muted-foreground w-24", children: "Analogous" }),
|
|
9042
|
+
/* @__PURE__ */ jsx42("div", { className: "flex gap-2", children: harmony.analogous.map((c) => /* @__PURE__ */ jsx42(
|
|
9043
|
+
Swatch,
|
|
9044
|
+
{
|
|
9045
|
+
color: c,
|
|
9046
|
+
ariaLabel: c,
|
|
9047
|
+
size: swatchSize,
|
|
9048
|
+
onClick: () => {
|
|
9049
|
+
const rgb = hexToRgb(c);
|
|
9050
|
+
const next = { r: rgb.r, g: rgb.g, b: rgb.b, a: rgba.a };
|
|
9051
|
+
setRgba(next);
|
|
9052
|
+
emit(next);
|
|
9053
|
+
}
|
|
9054
|
+
},
|
|
9055
|
+
c
|
|
9056
|
+
)) })
|
|
9057
|
+
] })
|
|
9058
|
+
] })
|
|
9059
|
+
] })
|
|
9060
|
+
] })
|
|
9061
|
+
}
|
|
9062
|
+
) });
|
|
9063
|
+
}
|
|
9064
|
+
|
|
9065
|
+
// ../../components/ui/Grid.tsx
|
|
9066
|
+
import React35, { useId as useId6 } from "react";
|
|
9067
|
+
import { Fragment as Fragment14, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
9068
|
+
var BP_MIN = {
|
|
9069
|
+
sm: 640,
|
|
9070
|
+
md: 768,
|
|
9071
|
+
lg: 1024,
|
|
9072
|
+
xl: 1280,
|
|
9073
|
+
"2xl": 1536
|
|
9074
|
+
};
|
|
9075
|
+
function toTemplateCols(columns, minColumnWidth) {
|
|
9076
|
+
if (minColumnWidth != null) {
|
|
9077
|
+
const v = typeof minColumnWidth === "number" ? `${minColumnWidth}px` : String(minColumnWidth);
|
|
9078
|
+
return `repeat(auto-fit, minmax(${v}, 1fr))`;
|
|
9079
|
+
}
|
|
9080
|
+
if (typeof columns === "number") return `repeat(${columns}, minmax(0, 1fr))`;
|
|
9081
|
+
if (columns) return String(columns);
|
|
9082
|
+
return `repeat(12, minmax(0, 1fr))`;
|
|
9083
|
+
}
|
|
9084
|
+
function toTemplateRows(rows) {
|
|
9085
|
+
if (typeof rows === "number") return `repeat(${rows}, minmax(0, auto))`;
|
|
9086
|
+
if (rows) return String(rows);
|
|
9087
|
+
return void 0;
|
|
9088
|
+
}
|
|
9089
|
+
function joinAreas(areas) {
|
|
9090
|
+
if (!areas) return void 0;
|
|
9091
|
+
return Array.isArray(areas) ? areas.join(" ") : areas;
|
|
9092
|
+
}
|
|
9093
|
+
function getVariantClasses(variant = "default", outlined) {
|
|
9094
|
+
if (outlined) {
|
|
9095
|
+
return "rounded-lg md:rounded-xl bg-card text-card-foreground border border-border shadow-sm";
|
|
9096
|
+
}
|
|
9097
|
+
const variants = {
|
|
9098
|
+
default: "",
|
|
9099
|
+
bordered: "border border-border rounded-lg",
|
|
9100
|
+
card: "rounded-lg md:rounded-xl bg-card text-card-foreground border border-border shadow-sm",
|
|
9101
|
+
flat: "bg-muted/30 rounded-lg",
|
|
9102
|
+
glass: "bg-background/80 backdrop-blur-sm border border-border/50 rounded-lg shadow-lg"
|
|
9103
|
+
};
|
|
9104
|
+
return variants[variant] || "";
|
|
9105
|
+
}
|
|
9106
|
+
var GridRoot = React35.forwardRef(
|
|
9107
|
+
({
|
|
9108
|
+
columns,
|
|
9109
|
+
rows,
|
|
9110
|
+
gap,
|
|
9111
|
+
gapX,
|
|
9112
|
+
gapY,
|
|
9113
|
+
autoRows,
|
|
9114
|
+
autoColumns,
|
|
9115
|
+
autoFlow,
|
|
9116
|
+
minColumnWidth,
|
|
9117
|
+
areas,
|
|
9118
|
+
alignItems,
|
|
9119
|
+
justifyItems,
|
|
9120
|
+
alignContent,
|
|
9121
|
+
justifyContent,
|
|
9122
|
+
responsive,
|
|
9123
|
+
variant = "default",
|
|
9124
|
+
animated = false,
|
|
9125
|
+
outlined = false,
|
|
9126
|
+
className,
|
|
9127
|
+
style,
|
|
9128
|
+
children,
|
|
9129
|
+
...rest
|
|
9130
|
+
}, ref) => {
|
|
9131
|
+
const id = useId6().replace(/[:]/g, "");
|
|
9132
|
+
const baseClass = `uv-grid-${id}`;
|
|
9133
|
+
const baseCols = toTemplateCols(columns, minColumnWidth);
|
|
9134
|
+
const baseRows = toTemplateRows(rows);
|
|
9135
|
+
const baseAreas = joinAreas(areas);
|
|
9136
|
+
let css = `.${baseClass}{display:grid;`;
|
|
9137
|
+
if (baseCols) css += `grid-template-columns:${baseCols};`;
|
|
9138
|
+
if (baseRows) css += `grid-template-rows:${baseRows};`;
|
|
9139
|
+
if (baseAreas) css += `grid-template-areas:${baseAreas};`;
|
|
9140
|
+
if (autoRows) css += `grid-auto-rows:${autoRows};`;
|
|
9141
|
+
if (autoColumns) css += `grid-auto-columns:${autoColumns};`;
|
|
9142
|
+
if (autoFlow) css += `grid-auto-flow:${autoFlow};`;
|
|
9143
|
+
if (alignItems) css += `align-items:${alignItems};`;
|
|
9144
|
+
if (justifyItems) css += `justify-items:${justifyItems};`;
|
|
9145
|
+
if (alignContent) css += `align-content:${alignContent};`;
|
|
9146
|
+
if (justifyContent) css += `justify-content:${justifyContent};`;
|
|
9147
|
+
if (animated) css += `transition:all 0.3s cubic-bezier(0.4, 0, 0.2, 1);`;
|
|
9148
|
+
css += `}`;
|
|
9149
|
+
const toVal = (v) => typeof v === "number" ? `${v}px` : v;
|
|
9150
|
+
const g = toVal(gap);
|
|
9151
|
+
const gx = toVal(gapX);
|
|
9152
|
+
const gy = toVal(gapY);
|
|
9153
|
+
if (g) css += `.${baseClass}{gap:${g};}`;
|
|
9154
|
+
if (gx) css += `.${baseClass}{column-gap:${gx};}`;
|
|
9155
|
+
if (gy) css += `.${baseClass}{row-gap:${gy};}`;
|
|
9156
|
+
if (responsive) {
|
|
9157
|
+
Object.keys(responsive).forEach((bp) => {
|
|
9158
|
+
const conf = responsive[bp];
|
|
9159
|
+
if (!conf) return;
|
|
9160
|
+
const cols = toTemplateCols(conf.columns, conf.minColumnWidth);
|
|
9161
|
+
const rws = toTemplateRows(conf.rows);
|
|
9162
|
+
const rg = toVal(conf.gap);
|
|
9163
|
+
const rgx = toVal(conf.gapX);
|
|
9164
|
+
const rgy = toVal(conf.gapY);
|
|
9165
|
+
css += `@media (min-width:${BP_MIN[bp]}px){.${baseClass}{`;
|
|
9166
|
+
if (cols) css += `grid-template-columns:${cols};`;
|
|
9167
|
+
if (rws) css += `grid-template-rows:${rws};`;
|
|
9168
|
+
if (rg) css += `gap:${rg};`;
|
|
9169
|
+
if (rgx) css += `column-gap:${rgx};`;
|
|
9170
|
+
if (rgy) css += `row-gap:${rgy};`;
|
|
9171
|
+
css += `}}`;
|
|
9172
|
+
});
|
|
9173
|
+
}
|
|
9174
|
+
return /* @__PURE__ */ jsxs38(
|
|
9175
|
+
"div",
|
|
9176
|
+
{
|
|
9177
|
+
ref,
|
|
9178
|
+
className: cn(
|
|
9179
|
+
baseClass,
|
|
9180
|
+
getVariantClasses(variant, outlined),
|
|
9181
|
+
animated && "transition-all duration-300 ease-in-out",
|
|
9182
|
+
className
|
|
9183
|
+
),
|
|
9184
|
+
style,
|
|
9185
|
+
...rest,
|
|
9186
|
+
children: [
|
|
9187
|
+
/* @__PURE__ */ jsx43("style", { dangerouslySetInnerHTML: { __html: css } }),
|
|
9188
|
+
children
|
|
9189
|
+
]
|
|
9190
|
+
}
|
|
9191
|
+
);
|
|
9192
|
+
}
|
|
9193
|
+
);
|
|
9194
|
+
GridRoot.displayName = "Grid";
|
|
9195
|
+
var GridItem = React35.forwardRef(
|
|
9196
|
+
({
|
|
9197
|
+
colSpan,
|
|
9198
|
+
rowSpan,
|
|
9199
|
+
colStart,
|
|
9200
|
+
colEnd,
|
|
9201
|
+
rowStart,
|
|
9202
|
+
rowEnd,
|
|
9203
|
+
area,
|
|
9204
|
+
alignSelf,
|
|
9205
|
+
justifySelf,
|
|
9206
|
+
order,
|
|
9207
|
+
hoverable = false,
|
|
9208
|
+
animationDelay,
|
|
9209
|
+
style,
|
|
9210
|
+
className,
|
|
9211
|
+
...rest
|
|
9212
|
+
}, ref) => {
|
|
9213
|
+
const st = { ...style };
|
|
9214
|
+
if (colSpan != null) st.gridColumn = `span ${colSpan} / span ${colSpan}`;
|
|
9215
|
+
if (rowSpan != null) st.gridRow = `span ${rowSpan} / span ${rowSpan}`;
|
|
9216
|
+
if (colStart != null) st.gridColumnStart = colStart;
|
|
9217
|
+
if (colEnd != null) st.gridColumnEnd = colEnd;
|
|
9218
|
+
if (rowStart != null) st.gridRowStart = rowStart;
|
|
9219
|
+
if (rowEnd != null) st.gridRowEnd = rowEnd;
|
|
9220
|
+
if (area) st.gridArea = area;
|
|
9221
|
+
if (alignSelf) st.alignSelf = alignSelf;
|
|
9222
|
+
if (justifySelf) st.justifySelf = justifySelf;
|
|
9223
|
+
if (order != null) st.order = order;
|
|
9224
|
+
if (animationDelay != null) {
|
|
9225
|
+
st.animationDelay = `${animationDelay}ms`;
|
|
9226
|
+
st.opacity = 0;
|
|
9227
|
+
st.animation = `uvGridItemFadeIn 0.5s ease-out forwards`;
|
|
9228
|
+
}
|
|
9229
|
+
return /* @__PURE__ */ jsxs38(Fragment14, { children: [
|
|
9230
|
+
animationDelay != null && /* @__PURE__ */ jsx43(
|
|
9231
|
+
"style",
|
|
9232
|
+
{
|
|
9233
|
+
dangerouslySetInnerHTML: {
|
|
9234
|
+
__html: `@keyframes uvGridItemFadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}`
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
),
|
|
9238
|
+
/* @__PURE__ */ jsx43(
|
|
9239
|
+
"div",
|
|
9240
|
+
{
|
|
9241
|
+
ref,
|
|
9242
|
+
className: cn(
|
|
9243
|
+
hoverable && "transition-all duration-200 hover:scale-[1.02] hover:shadow-md cursor-pointer",
|
|
9244
|
+
className
|
|
9245
|
+
),
|
|
9246
|
+
style: st,
|
|
9247
|
+
...rest
|
|
9248
|
+
}
|
|
9249
|
+
)
|
|
9250
|
+
] });
|
|
9251
|
+
}
|
|
9252
|
+
);
|
|
9253
|
+
GridItem.displayName = "Grid.Item";
|
|
9254
|
+
var Grid = Object.assign(GridRoot, { Item: GridItem });
|
|
9255
|
+
var Grid_default = Grid;
|
|
9256
|
+
|
|
7342
9257
|
// ../../components/ui/ClientOnly.tsx
|
|
7343
|
-
import { useEffect as
|
|
7344
|
-
import { Fragment as
|
|
9258
|
+
import { useEffect as useEffect18, useState as useState31 } from "react";
|
|
9259
|
+
import { Fragment as Fragment15, jsx as jsx44 } from "react/jsx-runtime";
|
|
7345
9260
|
function ClientOnly({ children, fallback = null }) {
|
|
7346
|
-
const [hasMounted, setHasMounted] =
|
|
7347
|
-
|
|
9261
|
+
const [hasMounted, setHasMounted] = useState31(false);
|
|
9262
|
+
useEffect18(() => {
|
|
7348
9263
|
setHasMounted(true);
|
|
7349
9264
|
}, []);
|
|
7350
9265
|
if (!hasMounted) {
|
|
7351
|
-
return /* @__PURE__ */
|
|
9266
|
+
return /* @__PURE__ */ jsx44(Fragment15, { children: fallback });
|
|
7352
9267
|
}
|
|
7353
|
-
return /* @__PURE__ */
|
|
9268
|
+
return /* @__PURE__ */ jsx44(Fragment15, { children });
|
|
7354
9269
|
}
|
|
7355
9270
|
|
|
7356
9271
|
// ../../components/ui/Loading.tsx
|
|
7357
9272
|
import { Activity as Activity3 } from "lucide-react";
|
|
7358
|
-
import { jsx as
|
|
9273
|
+
import { jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
7359
9274
|
var LoadingSpinner = ({
|
|
7360
9275
|
size = "md",
|
|
7361
9276
|
className,
|
|
@@ -7371,7 +9286,7 @@ var LoadingSpinner = ({
|
|
|
7371
9286
|
foreground: "text-foreground",
|
|
7372
9287
|
muted: "text-muted-foreground"
|
|
7373
9288
|
};
|
|
7374
|
-
return /* @__PURE__ */
|
|
9289
|
+
return /* @__PURE__ */ jsx45(
|
|
7375
9290
|
Activity3,
|
|
7376
9291
|
{
|
|
7377
9292
|
className: cn(
|
|
@@ -7392,7 +9307,7 @@ var LoadingDots = ({
|
|
|
7392
9307
|
foreground: "bg-foreground",
|
|
7393
9308
|
muted: "bg-muted-foreground"
|
|
7394
9309
|
};
|
|
7395
|
-
return /* @__PURE__ */
|
|
9310
|
+
return /* @__PURE__ */ jsx45("div", { className: cn("flex items-center space-x-1", className), children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx45(
|
|
7396
9311
|
"div",
|
|
7397
9312
|
{
|
|
7398
9313
|
className: cn(
|
|
@@ -7414,7 +9329,7 @@ var LoadingBar = ({
|
|
|
7414
9329
|
label
|
|
7415
9330
|
}) => {
|
|
7416
9331
|
const pct = progress ? Math.min(Math.max(progress, 0), 100) : void 0;
|
|
7417
|
-
return /* @__PURE__ */
|
|
9332
|
+
return /* @__PURE__ */ jsx45(
|
|
7418
9333
|
"div",
|
|
7419
9334
|
{
|
|
7420
9335
|
className: cn("w-full bg-muted rounded-full h-2", className),
|
|
@@ -7423,7 +9338,7 @@ var LoadingBar = ({
|
|
|
7423
9338
|
"aria-valuemax": pct === void 0 ? void 0 : 100,
|
|
7424
9339
|
"aria-valuenow": pct === void 0 ? void 0 : Math.round(pct),
|
|
7425
9340
|
"aria-label": label || "Loading",
|
|
7426
|
-
children: /* @__PURE__ */
|
|
9341
|
+
children: /* @__PURE__ */ jsx45(
|
|
7427
9342
|
"div",
|
|
7428
9343
|
{
|
|
7429
9344
|
className: cn(
|
|
@@ -7440,10 +9355,10 @@ var LoadingBar = ({
|
|
|
7440
9355
|
};
|
|
7441
9356
|
|
|
7442
9357
|
// ../../components/ui/Table.tsx
|
|
7443
|
-
import
|
|
7444
|
-
import { jsx as
|
|
7445
|
-
var Table =
|
|
7446
|
-
({ className, containerClassName, ...props }, ref) => /* @__PURE__ */
|
|
9358
|
+
import React36 from "react";
|
|
9359
|
+
import { jsx as jsx46, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
9360
|
+
var Table = React36.forwardRef(
|
|
9361
|
+
({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7447
9362
|
"div",
|
|
7448
9363
|
{
|
|
7449
9364
|
className: cn(
|
|
@@ -7453,7 +9368,7 @@ var Table = React29.forwardRef(
|
|
|
7453
9368
|
"backdrop-blur-sm transition-all duration-300",
|
|
7454
9369
|
containerClassName
|
|
7455
9370
|
),
|
|
7456
|
-
children: /* @__PURE__ */
|
|
9371
|
+
children: /* @__PURE__ */ jsx46(
|
|
7457
9372
|
"table",
|
|
7458
9373
|
{
|
|
7459
9374
|
ref,
|
|
@@ -7465,8 +9380,8 @@ var Table = React29.forwardRef(
|
|
|
7465
9380
|
)
|
|
7466
9381
|
);
|
|
7467
9382
|
Table.displayName = "Table";
|
|
7468
|
-
var TableHeader =
|
|
7469
|
-
({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */
|
|
9383
|
+
var TableHeader = React36.forwardRef(
|
|
9384
|
+
({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ jsxs40(
|
|
7470
9385
|
"thead",
|
|
7471
9386
|
{
|
|
7472
9387
|
ref,
|
|
@@ -7484,7 +9399,7 @@ var TableHeader = React29.forwardRef(
|
|
|
7484
9399
|
)
|
|
7485
9400
|
);
|
|
7486
9401
|
TableHeader.displayName = "TableHeader";
|
|
7487
|
-
var TableBody =
|
|
9402
|
+
var TableBody = React36.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7488
9403
|
"tbody",
|
|
7489
9404
|
{
|
|
7490
9405
|
ref,
|
|
@@ -7493,7 +9408,7 @@ var TableBody = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
7493
9408
|
}
|
|
7494
9409
|
));
|
|
7495
9410
|
TableBody.displayName = "TableBody";
|
|
7496
|
-
var TableFooter =
|
|
9411
|
+
var TableFooter = React36.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7497
9412
|
"tfoot",
|
|
7498
9413
|
{
|
|
7499
9414
|
ref,
|
|
@@ -7505,7 +9420,7 @@ var TableFooter = React29.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
7505
9420
|
}
|
|
7506
9421
|
));
|
|
7507
9422
|
TableFooter.displayName = "TableFooter";
|
|
7508
|
-
var TableRow =
|
|
9423
|
+
var TableRow = React36.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7509
9424
|
"tr",
|
|
7510
9425
|
{
|
|
7511
9426
|
ref,
|
|
@@ -7519,7 +9434,7 @@ var TableRow = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
7519
9434
|
}
|
|
7520
9435
|
));
|
|
7521
9436
|
TableRow.displayName = "TableRow";
|
|
7522
|
-
var TableHead =
|
|
9437
|
+
var TableHead = React36.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7523
9438
|
"th",
|
|
7524
9439
|
{
|
|
7525
9440
|
ref,
|
|
@@ -7531,7 +9446,7 @@ var TableHead = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
7531
9446
|
}
|
|
7532
9447
|
));
|
|
7533
9448
|
TableHead.displayName = "TableHead";
|
|
7534
|
-
var TableCell =
|
|
9449
|
+
var TableCell = React36.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7535
9450
|
"td",
|
|
7536
9451
|
{
|
|
7537
9452
|
ref,
|
|
@@ -7540,7 +9455,7 @@ var TableCell = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
7540
9455
|
}
|
|
7541
9456
|
));
|
|
7542
9457
|
TableCell.displayName = "TableCell";
|
|
7543
|
-
var TableCaption =
|
|
9458
|
+
var TableCaption = React36.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx46(
|
|
7544
9459
|
"caption",
|
|
7545
9460
|
{
|
|
7546
9461
|
ref,
|
|
@@ -7552,12 +9467,12 @@ TableCaption.displayName = "TableCaption";
|
|
|
7552
9467
|
|
|
7553
9468
|
// ../../components/ui/DataTable.tsx
|
|
7554
9469
|
import { Filter as FilterIcon } from "lucide-react";
|
|
7555
|
-
import
|
|
9470
|
+
import React37 from "react";
|
|
7556
9471
|
import { useTranslations as useTranslations7 } from "next-intl";
|
|
7557
|
-
import { jsx as
|
|
9472
|
+
import { jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
7558
9473
|
function useDebounced(value, delay = 300) {
|
|
7559
|
-
const [debounced, setDebounced] =
|
|
7560
|
-
|
|
9474
|
+
const [debounced, setDebounced] = React37.useState(value);
|
|
9475
|
+
React37.useEffect(() => {
|
|
7561
9476
|
const id = setTimeout(() => setDebounced(value), delay);
|
|
7562
9477
|
return () => clearTimeout(id);
|
|
7563
9478
|
}, [value, delay]);
|
|
@@ -7584,20 +9499,20 @@ function DataTable({
|
|
|
7584
9499
|
labels
|
|
7585
9500
|
}) {
|
|
7586
9501
|
const t = useTranslations7("Common");
|
|
7587
|
-
const [visibleCols, setVisibleCols] =
|
|
7588
|
-
const [filters, setFilters] =
|
|
7589
|
-
const [sort, setSort] =
|
|
7590
|
-
const [density, setDensity] =
|
|
7591
|
-
const [curPage, setCurPage] =
|
|
7592
|
-
const [curPageSize, setCurPageSize] =
|
|
9502
|
+
const [visibleCols, setVisibleCols] = React37.useState(() => columns.filter((c) => c.visible !== false).map((c) => c.key));
|
|
9503
|
+
const [filters, setFilters] = React37.useState({});
|
|
9504
|
+
const [sort, setSort] = React37.useState(null);
|
|
9505
|
+
const [density, setDensity] = React37.useState("normal");
|
|
9506
|
+
const [curPage, setCurPage] = React37.useState(page);
|
|
9507
|
+
const [curPageSize, setCurPageSize] = React37.useState(pageSize);
|
|
7593
9508
|
const debouncedFilters = useDebounced(filters, 350);
|
|
7594
|
-
|
|
9509
|
+
React37.useEffect(() => {
|
|
7595
9510
|
setCurPage(page);
|
|
7596
9511
|
}, [page]);
|
|
7597
|
-
|
|
9512
|
+
React37.useEffect(() => {
|
|
7598
9513
|
setCurPageSize(pageSize);
|
|
7599
9514
|
}, [pageSize]);
|
|
7600
|
-
|
|
9515
|
+
React37.useEffect(() => {
|
|
7601
9516
|
if (!onQueryChange) return;
|
|
7602
9517
|
onQueryChange({ filters: debouncedFilters, sort, page: curPage, pageSize: curPageSize });
|
|
7603
9518
|
}, [debouncedFilters, sort, curPage, curPageSize]);
|
|
@@ -7616,7 +9531,7 @@ function DataTable({
|
|
|
7616
9531
|
className: "h-8 w-full text-sm"
|
|
7617
9532
|
};
|
|
7618
9533
|
if (col.filter.type === "text") {
|
|
7619
|
-
return /* @__PURE__ */
|
|
9534
|
+
return /* @__PURE__ */ jsx47(
|
|
7620
9535
|
Input_default,
|
|
7621
9536
|
{
|
|
7622
9537
|
...commonProps,
|
|
@@ -7631,7 +9546,7 @@ function DataTable({
|
|
|
7631
9546
|
}
|
|
7632
9547
|
if (col.filter.type === "select") {
|
|
7633
9548
|
const options = col.filter.options || [];
|
|
7634
|
-
return /* @__PURE__ */
|
|
9549
|
+
return /* @__PURE__ */ jsx47(
|
|
7635
9550
|
Combobox,
|
|
7636
9551
|
{
|
|
7637
9552
|
options: ["", ...options],
|
|
@@ -7647,7 +9562,7 @@ function DataTable({
|
|
|
7647
9562
|
);
|
|
7648
9563
|
}
|
|
7649
9564
|
if (col.filter.type === "date") {
|
|
7650
|
-
return /* @__PURE__ */
|
|
9565
|
+
return /* @__PURE__ */ jsx47(
|
|
7651
9566
|
DatePicker,
|
|
7652
9567
|
{
|
|
7653
9568
|
placeholder: col.filter.placeholder || `Select ${String(col.title)}`,
|
|
@@ -7661,7 +9576,7 @@ function DataTable({
|
|
|
7661
9576
|
}
|
|
7662
9577
|
return null;
|
|
7663
9578
|
};
|
|
7664
|
-
const renderHeader = /* @__PURE__ */
|
|
9579
|
+
const renderHeader = /* @__PURE__ */ jsx47(TableRow, { children: visibleColumns.map((col, colIdx) => /* @__PURE__ */ jsx47(
|
|
7665
9580
|
TableHead,
|
|
7666
9581
|
{
|
|
7667
9582
|
style: { width: col.width },
|
|
@@ -7670,10 +9585,10 @@ function DataTable({
|
|
|
7670
9585
|
col.align === "center" && "text-center",
|
|
7671
9586
|
columnDividers && colIdx > 0 && "border-l border-border/60"
|
|
7672
9587
|
),
|
|
7673
|
-
children: /* @__PURE__ */
|
|
7674
|
-
/* @__PURE__ */
|
|
7675
|
-
/* @__PURE__ */
|
|
7676
|
-
col.sortable && /* @__PURE__ */
|
|
9588
|
+
children: /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between gap-2 select-none min-h-[2.5rem]", children: [
|
|
9589
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-1 min-w-0 flex-1", children: [
|
|
9590
|
+
/* @__PURE__ */ jsx47("span", { className: "truncate font-medium text-sm", children: col.title }),
|
|
9591
|
+
col.sortable && /* @__PURE__ */ jsx47(
|
|
7677
9592
|
"button",
|
|
7678
9593
|
{
|
|
7679
9594
|
className: cn(
|
|
@@ -7690,8 +9605,8 @@ function DataTable({
|
|
|
7690
9605
|
},
|
|
7691
9606
|
"aria-label": "Sort",
|
|
7692
9607
|
title: `Sort by ${String(col.title)}`,
|
|
7693
|
-
children: /* @__PURE__ */
|
|
7694
|
-
/* @__PURE__ */
|
|
9608
|
+
children: /* @__PURE__ */ jsxs41("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
|
|
9609
|
+
/* @__PURE__ */ jsx47(
|
|
7695
9610
|
"path",
|
|
7696
9611
|
{
|
|
7697
9612
|
d: "M7 8l3-3 3 3",
|
|
@@ -7702,7 +9617,7 @@ function DataTable({
|
|
|
7702
9617
|
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
7703
9618
|
}
|
|
7704
9619
|
),
|
|
7705
|
-
/* @__PURE__ */
|
|
9620
|
+
/* @__PURE__ */ jsx47(
|
|
7706
9621
|
"path",
|
|
7707
9622
|
{
|
|
7708
9623
|
d: "M7 12l3 3 3-3",
|
|
@@ -7717,11 +9632,11 @@ function DataTable({
|
|
|
7717
9632
|
}
|
|
7718
9633
|
)
|
|
7719
9634
|
] }),
|
|
7720
|
-
col.filter && /* @__PURE__ */
|
|
9635
|
+
col.filter && /* @__PURE__ */ jsx47(
|
|
7721
9636
|
Popover,
|
|
7722
9637
|
{
|
|
7723
9638
|
placement: "bottom-start",
|
|
7724
|
-
trigger: /* @__PURE__ */
|
|
9639
|
+
trigger: /* @__PURE__ */ jsx47(
|
|
7725
9640
|
"button",
|
|
7726
9641
|
{
|
|
7727
9642
|
className: cn(
|
|
@@ -7731,16 +9646,16 @@ function DataTable({
|
|
|
7731
9646
|
),
|
|
7732
9647
|
"aria-label": "Filter",
|
|
7733
9648
|
title: "Filter",
|
|
7734
|
-
children: /* @__PURE__ */
|
|
9649
|
+
children: /* @__PURE__ */ jsx47(FilterIcon, { className: "h-4 w-4" })
|
|
7735
9650
|
}
|
|
7736
9651
|
),
|
|
7737
|
-
children: /* @__PURE__ */
|
|
7738
|
-
/* @__PURE__ */
|
|
9652
|
+
children: /* @__PURE__ */ jsxs41("div", { className: "w-48 p-2 space-y-2", children: [
|
|
9653
|
+
/* @__PURE__ */ jsxs41("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
|
|
7739
9654
|
"Filter ",
|
|
7740
9655
|
col.title
|
|
7741
9656
|
] }),
|
|
7742
9657
|
renderFilterControl(col),
|
|
7743
|
-
filters[col.key] && /* @__PURE__ */
|
|
9658
|
+
filters[col.key] && /* @__PURE__ */ jsx47(
|
|
7744
9659
|
"button",
|
|
7745
9660
|
{
|
|
7746
9661
|
onClick: () => {
|
|
@@ -7763,20 +9678,20 @@ function DataTable({
|
|
|
7763
9678
|
col.key
|
|
7764
9679
|
)) });
|
|
7765
9680
|
const isServerMode = Boolean(onQueryChange);
|
|
7766
|
-
const displayedData = isServerMode ? data :
|
|
9681
|
+
const displayedData = isServerMode ? data : React37.useMemo(() => {
|
|
7767
9682
|
const start = (curPage - 1) * curPageSize;
|
|
7768
9683
|
return data.slice(start, start + curPageSize);
|
|
7769
9684
|
}, [data, curPage, curPageSize]);
|
|
7770
9685
|
const totalItems = isServerMode ? total : data.length;
|
|
7771
|
-
return /* @__PURE__ */
|
|
7772
|
-
/* @__PURE__ */
|
|
7773
|
-
/* @__PURE__ */
|
|
7774
|
-
/* @__PURE__ */
|
|
7775
|
-
enableDensityToggle && /* @__PURE__ */
|
|
9686
|
+
return /* @__PURE__ */ jsxs41("div", { className: cn("space-y-2", className), children: [
|
|
9687
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
|
|
9688
|
+
/* @__PURE__ */ jsx47("div", { className: "text-sm text-muted-foreground", children: caption }),
|
|
9689
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-2", children: [
|
|
9690
|
+
enableDensityToggle && /* @__PURE__ */ jsx47(
|
|
7776
9691
|
DropdownMenu_default,
|
|
7777
9692
|
{
|
|
7778
|
-
trigger: /* @__PURE__ */
|
|
7779
|
-
/* @__PURE__ */
|
|
9693
|
+
trigger: /* @__PURE__ */ jsxs41(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
|
|
9694
|
+
/* @__PURE__ */ jsx47("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx47("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
7780
9695
|
labels?.density || t("density")
|
|
7781
9696
|
] }),
|
|
7782
9697
|
items: [
|
|
@@ -7786,11 +9701,11 @@ function DataTable({
|
|
|
7786
9701
|
]
|
|
7787
9702
|
}
|
|
7788
9703
|
),
|
|
7789
|
-
enableColumnVisibilityToggle && /* @__PURE__ */
|
|
9704
|
+
enableColumnVisibilityToggle && /* @__PURE__ */ jsx47(
|
|
7790
9705
|
DropdownMenu_default,
|
|
7791
9706
|
{
|
|
7792
|
-
trigger: /* @__PURE__ */
|
|
7793
|
-
/* @__PURE__ */
|
|
9707
|
+
trigger: /* @__PURE__ */ jsxs41(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
|
|
9708
|
+
/* @__PURE__ */ jsx47("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx47(
|
|
7794
9709
|
"path",
|
|
7795
9710
|
{
|
|
7796
9711
|
strokeLinecap: "round",
|
|
@@ -7801,15 +9716,15 @@ function DataTable({
|
|
|
7801
9716
|
) }),
|
|
7802
9717
|
labels?.columns || t("columns")
|
|
7803
9718
|
] }),
|
|
7804
|
-
children: columns.map((c) => /* @__PURE__ */
|
|
9719
|
+
children: columns.map((c) => /* @__PURE__ */ jsxs41(
|
|
7805
9720
|
DropdownMenuItem,
|
|
7806
9721
|
{
|
|
7807
9722
|
onClick: () => {
|
|
7808
9723
|
setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
|
|
7809
9724
|
},
|
|
7810
9725
|
children: [
|
|
7811
|
-
/* @__PURE__ */
|
|
7812
|
-
/* @__PURE__ */
|
|
9726
|
+
/* @__PURE__ */ jsx47("input", { type: "checkbox", className: "mr-2 rounded border-border", readOnly: true, checked: visibleCols.includes(c.key) }),
|
|
9727
|
+
/* @__PURE__ */ jsx47("span", { className: "truncate", children: c.title })
|
|
7813
9728
|
]
|
|
7814
9729
|
},
|
|
7815
9730
|
c.key
|
|
@@ -7819,17 +9734,17 @@ function DataTable({
|
|
|
7819
9734
|
toolbar
|
|
7820
9735
|
] })
|
|
7821
9736
|
] }),
|
|
7822
|
-
/* @__PURE__ */
|
|
9737
|
+
/* @__PURE__ */ jsx47("div", { className: cn("relative rounded-md border border-border/50 overflow-hidden", loading2 && "opacity-60 pointer-events-none"), children: /* @__PURE__ */ jsxs41(
|
|
7823
9738
|
Table,
|
|
7824
9739
|
{
|
|
7825
9740
|
containerClassName: "border-0 md:border-0 rounded-none md:rounded-none shadow-none bg-transparent",
|
|
7826
9741
|
className: "[&_thead]:sticky [&_thead]:top-0 [&_thead]:z-[5] [&_thead]:bg-background [&_thead]:backdrop-blur-sm",
|
|
7827
9742
|
children: [
|
|
7828
|
-
/* @__PURE__ */
|
|
7829
|
-
/* @__PURE__ */
|
|
7830
|
-
/* @__PURE__ */
|
|
7831
|
-
/* @__PURE__ */
|
|
7832
|
-
/* @__PURE__ */
|
|
9743
|
+
/* @__PURE__ */ jsx47(TableHeader, { children: renderHeader }),
|
|
9744
|
+
/* @__PURE__ */ jsx47(TableBody, { children: loading2 ? /* @__PURE__ */ jsx47(TableRow, { children: /* @__PURE__ */ jsx47(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
|
|
9745
|
+
/* @__PURE__ */ jsxs41("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
9746
|
+
/* @__PURE__ */ jsx47("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
9747
|
+
/* @__PURE__ */ jsx47(
|
|
7833
9748
|
"path",
|
|
7834
9749
|
{
|
|
7835
9750
|
className: "opacity-75",
|
|
@@ -7838,10 +9753,10 @@ function DataTable({
|
|
|
7838
9753
|
}
|
|
7839
9754
|
)
|
|
7840
9755
|
] }),
|
|
7841
|
-
/* @__PURE__ */
|
|
7842
|
-
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */
|
|
9756
|
+
/* @__PURE__ */ jsx47("span", { className: "text-sm", children: "Loading..." })
|
|
9757
|
+
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ jsx47(TableRow, { children: /* @__PURE__ */ jsx47(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: "No data" }) }) : displayedData.map((row, idx) => /* @__PURE__ */ jsx47(TableRow, { className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/30"), children: visibleColumns.map((col, colIdx) => {
|
|
7843
9758
|
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
7844
|
-
return /* @__PURE__ */
|
|
9759
|
+
return /* @__PURE__ */ jsx47(
|
|
7845
9760
|
TableCell,
|
|
7846
9761
|
{
|
|
7847
9762
|
className: cn(
|
|
@@ -7860,7 +9775,7 @@ function DataTable({
|
|
|
7860
9775
|
]
|
|
7861
9776
|
}
|
|
7862
9777
|
) }),
|
|
7863
|
-
totalItems > 0 && /* @__PURE__ */
|
|
9778
|
+
totalItems > 0 && /* @__PURE__ */ jsx47("div", { className: "border-t bg-muted/30 p-4 rounded-b-md", children: /* @__PURE__ */ jsx47(
|
|
7864
9779
|
Pagination,
|
|
7865
9780
|
{
|
|
7866
9781
|
page: curPage,
|
|
@@ -7882,10 +9797,10 @@ function DataTable({
|
|
|
7882
9797
|
var DataTable_default = DataTable;
|
|
7883
9798
|
|
|
7884
9799
|
// ../../components/ui/Form.tsx
|
|
7885
|
-
import * as
|
|
9800
|
+
import * as React39 from "react";
|
|
7886
9801
|
|
|
7887
9802
|
// ../../node_modules/react-hook-form/dist/index.esm.mjs
|
|
7888
|
-
import
|
|
9803
|
+
import React38 from "react";
|
|
7889
9804
|
var isCheckBoxInput = (element) => element.type === "checkbox";
|
|
7890
9805
|
var isDateObject = (value) => value instanceof Date;
|
|
7891
9806
|
var isNullOrUndefined = (value) => value == null;
|
|
@@ -7973,12 +9888,12 @@ var INPUT_VALIDATION_RULES = {
|
|
|
7973
9888
|
required: "required",
|
|
7974
9889
|
validate: "validate"
|
|
7975
9890
|
};
|
|
7976
|
-
var HookFormContext =
|
|
9891
|
+
var HookFormContext = React38.createContext(null);
|
|
7977
9892
|
HookFormContext.displayName = "HookFormContext";
|
|
7978
|
-
var useFormContext = () =>
|
|
9893
|
+
var useFormContext = () => React38.useContext(HookFormContext);
|
|
7979
9894
|
var FormProvider = (props) => {
|
|
7980
9895
|
const { children, ...data } = props;
|
|
7981
|
-
return
|
|
9896
|
+
return React38.createElement(HookFormContext.Provider, { value: data }, children);
|
|
7982
9897
|
};
|
|
7983
9898
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
7984
9899
|
const result = {
|
|
@@ -7998,12 +9913,12 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
|
7998
9913
|
}
|
|
7999
9914
|
return result;
|
|
8000
9915
|
};
|
|
8001
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
9916
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React38.useLayoutEffect : React38.useEffect;
|
|
8002
9917
|
function useFormState(props) {
|
|
8003
9918
|
const methods = useFormContext();
|
|
8004
9919
|
const { control = methods.control, disabled, name, exact } = props || {};
|
|
8005
|
-
const [formState, updateFormState] =
|
|
8006
|
-
const _localProxyFormState =
|
|
9920
|
+
const [formState, updateFormState] = React38.useState(control._formState);
|
|
9921
|
+
const _localProxyFormState = React38.useRef({
|
|
8007
9922
|
isDirty: false,
|
|
8008
9923
|
isLoading: false,
|
|
8009
9924
|
dirtyFields: false,
|
|
@@ -8024,10 +9939,10 @@ function useFormState(props) {
|
|
|
8024
9939
|
});
|
|
8025
9940
|
}
|
|
8026
9941
|
}), [name, disabled, exact]);
|
|
8027
|
-
|
|
9942
|
+
React38.useEffect(() => {
|
|
8028
9943
|
_localProxyFormState.current.isValid && control._setValid(true);
|
|
8029
9944
|
}, [control]);
|
|
8030
|
-
return
|
|
9945
|
+
return React38.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
|
|
8031
9946
|
}
|
|
8032
9947
|
var isString = (value) => typeof value === "string";
|
|
8033
9948
|
var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
|
|
@@ -8076,12 +9991,12 @@ function deepEqual(object1, object2, _internal_visited = /* @__PURE__ */ new Wea
|
|
|
8076
9991
|
function useWatch(props) {
|
|
8077
9992
|
const methods = useFormContext();
|
|
8078
9993
|
const { control = methods.control, name, defaultValue, disabled, exact, compute } = props || {};
|
|
8079
|
-
const _defaultValue =
|
|
8080
|
-
const _compute =
|
|
8081
|
-
const _computeFormValues =
|
|
9994
|
+
const _defaultValue = React38.useRef(defaultValue);
|
|
9995
|
+
const _compute = React38.useRef(compute);
|
|
9996
|
+
const _computeFormValues = React38.useRef(void 0);
|
|
8082
9997
|
_compute.current = compute;
|
|
8083
|
-
const defaultValueMemo =
|
|
8084
|
-
const [value, updateValue] =
|
|
9998
|
+
const defaultValueMemo = React38.useMemo(() => control._getWatch(name, _defaultValue.current), [control, name]);
|
|
9999
|
+
const [value, updateValue] = React38.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo);
|
|
8085
10000
|
useIsomorphicLayoutEffect(() => control._subscribe({
|
|
8086
10001
|
name,
|
|
8087
10002
|
formState: {
|
|
@@ -8103,14 +10018,14 @@ function useWatch(props) {
|
|
|
8103
10018
|
}
|
|
8104
10019
|
}
|
|
8105
10020
|
}), [control, disabled, name, exact]);
|
|
8106
|
-
|
|
10021
|
+
React38.useEffect(() => control._removeUnmounted());
|
|
8107
10022
|
return value;
|
|
8108
10023
|
}
|
|
8109
10024
|
function useController(props) {
|
|
8110
10025
|
const methods = useFormContext();
|
|
8111
10026
|
const { name, disabled, control = methods.control, shouldUnregister, defaultValue } = props;
|
|
8112
10027
|
const isArrayField = isNameInFieldArray(control._names.array, name);
|
|
8113
|
-
const defaultValueMemo =
|
|
10028
|
+
const defaultValueMemo = React38.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
|
8114
10029
|
const value = useWatch({
|
|
8115
10030
|
control,
|
|
8116
10031
|
name,
|
|
@@ -8122,15 +10037,15 @@ function useController(props) {
|
|
|
8122
10037
|
name,
|
|
8123
10038
|
exact: true
|
|
8124
10039
|
});
|
|
8125
|
-
const _props =
|
|
8126
|
-
const _previousNameRef =
|
|
8127
|
-
const _registerProps =
|
|
10040
|
+
const _props = React38.useRef(props);
|
|
10041
|
+
const _previousNameRef = React38.useRef(void 0);
|
|
10042
|
+
const _registerProps = React38.useRef(control.register(name, {
|
|
8128
10043
|
...props.rules,
|
|
8129
10044
|
value,
|
|
8130
10045
|
...isBoolean(props.disabled) ? { disabled: props.disabled } : {}
|
|
8131
10046
|
}));
|
|
8132
10047
|
_props.current = props;
|
|
8133
|
-
const fieldState =
|
|
10048
|
+
const fieldState = React38.useMemo(() => Object.defineProperties({}, {
|
|
8134
10049
|
invalid: {
|
|
8135
10050
|
enumerable: true,
|
|
8136
10051
|
get: () => !!get(formState.errors, name)
|
|
@@ -8152,21 +10067,21 @@ function useController(props) {
|
|
|
8152
10067
|
get: () => get(formState.errors, name)
|
|
8153
10068
|
}
|
|
8154
10069
|
}), [formState, name]);
|
|
8155
|
-
const onChange =
|
|
10070
|
+
const onChange = React38.useCallback((event) => _registerProps.current.onChange({
|
|
8156
10071
|
target: {
|
|
8157
10072
|
value: getEventValue(event),
|
|
8158
10073
|
name
|
|
8159
10074
|
},
|
|
8160
10075
|
type: EVENTS.CHANGE
|
|
8161
10076
|
}), [name]);
|
|
8162
|
-
const onBlur =
|
|
10077
|
+
const onBlur = React38.useCallback(() => _registerProps.current.onBlur({
|
|
8163
10078
|
target: {
|
|
8164
10079
|
value: get(control._formValues, name),
|
|
8165
10080
|
name
|
|
8166
10081
|
},
|
|
8167
10082
|
type: EVENTS.BLUR
|
|
8168
10083
|
}), [name, control._formValues]);
|
|
8169
|
-
const ref =
|
|
10084
|
+
const ref = React38.useCallback((elm) => {
|
|
8170
10085
|
const field2 = get(control._fields, name);
|
|
8171
10086
|
if (field2 && elm) {
|
|
8172
10087
|
field2._f.ref = {
|
|
@@ -8177,7 +10092,7 @@ function useController(props) {
|
|
|
8177
10092
|
};
|
|
8178
10093
|
}
|
|
8179
10094
|
}, [control._fields, name]);
|
|
8180
|
-
const field =
|
|
10095
|
+
const field = React38.useMemo(() => ({
|
|
8181
10096
|
name,
|
|
8182
10097
|
value,
|
|
8183
10098
|
...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {},
|
|
@@ -8185,7 +10100,7 @@ function useController(props) {
|
|
|
8185
10100
|
onBlur,
|
|
8186
10101
|
ref
|
|
8187
10102
|
}), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
|
|
8188
|
-
|
|
10103
|
+
React38.useEffect(() => {
|
|
8189
10104
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
|
8190
10105
|
const previousName = _previousNameRef.current;
|
|
8191
10106
|
if (previousName && previousName !== name && !isArrayField) {
|
|
@@ -8215,13 +10130,13 @@ function useController(props) {
|
|
|
8215
10130
|
(isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false);
|
|
8216
10131
|
};
|
|
8217
10132
|
}, [name, control, isArrayField, shouldUnregister]);
|
|
8218
|
-
|
|
10133
|
+
React38.useEffect(() => {
|
|
8219
10134
|
control._setDisabledField({
|
|
8220
10135
|
disabled,
|
|
8221
10136
|
name
|
|
8222
10137
|
});
|
|
8223
10138
|
}, [disabled, name, control]);
|
|
8224
|
-
return
|
|
10139
|
+
return React38.useMemo(() => ({
|
|
8225
10140
|
field,
|
|
8226
10141
|
formState,
|
|
8227
10142
|
fieldState
|
|
@@ -9540,9 +11455,9 @@ function createFormControl(props = {}) {
|
|
|
9540
11455
|
};
|
|
9541
11456
|
}
|
|
9542
11457
|
function useForm(props = {}) {
|
|
9543
|
-
const _formControl =
|
|
9544
|
-
const _values =
|
|
9545
|
-
const [formState, updateFormState] =
|
|
11458
|
+
const _formControl = React38.useRef(void 0);
|
|
11459
|
+
const _values = React38.useRef(void 0);
|
|
11460
|
+
const [formState, updateFormState] = React38.useState({
|
|
9546
11461
|
isDirty: false,
|
|
9547
11462
|
isValidating: false,
|
|
9548
11463
|
isLoading: isFunction(props.defaultValues),
|
|
@@ -9591,8 +11506,8 @@ function useForm(props = {}) {
|
|
|
9591
11506
|
control._formState.isReady = true;
|
|
9592
11507
|
return sub;
|
|
9593
11508
|
}, [control]);
|
|
9594
|
-
|
|
9595
|
-
|
|
11509
|
+
React38.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
|
11510
|
+
React38.useEffect(() => {
|
|
9596
11511
|
if (props.mode) {
|
|
9597
11512
|
control._options.mode = props.mode;
|
|
9598
11513
|
}
|
|
@@ -9600,18 +11515,18 @@ function useForm(props = {}) {
|
|
|
9600
11515
|
control._options.reValidateMode = props.reValidateMode;
|
|
9601
11516
|
}
|
|
9602
11517
|
}, [control, props.mode, props.reValidateMode]);
|
|
9603
|
-
|
|
11518
|
+
React38.useEffect(() => {
|
|
9604
11519
|
if (props.errors) {
|
|
9605
11520
|
control._setErrors(props.errors);
|
|
9606
11521
|
control._focusError();
|
|
9607
11522
|
}
|
|
9608
11523
|
}, [control, props.errors]);
|
|
9609
|
-
|
|
11524
|
+
React38.useEffect(() => {
|
|
9610
11525
|
props.shouldUnregister && control._subjects.state.next({
|
|
9611
11526
|
values: control._getWatch()
|
|
9612
11527
|
});
|
|
9613
11528
|
}, [control, props.shouldUnregister]);
|
|
9614
|
-
|
|
11529
|
+
React38.useEffect(() => {
|
|
9615
11530
|
if (control._proxyFormState.isDirty) {
|
|
9616
11531
|
const isDirty = control._getDirty();
|
|
9617
11532
|
if (isDirty !== formState.isDirty) {
|
|
@@ -9621,7 +11536,7 @@ function useForm(props = {}) {
|
|
|
9621
11536
|
}
|
|
9622
11537
|
}
|
|
9623
11538
|
}, [control, formState.isDirty]);
|
|
9624
|
-
|
|
11539
|
+
React38.useEffect(() => {
|
|
9625
11540
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
|
9626
11541
|
control._reset(props.values, {
|
|
9627
11542
|
keepFieldsRef: true,
|
|
@@ -9633,7 +11548,7 @@ function useForm(props = {}) {
|
|
|
9633
11548
|
control._resetDefaultValues();
|
|
9634
11549
|
}
|
|
9635
11550
|
}, [control, props.values]);
|
|
9636
|
-
|
|
11551
|
+
React38.useEffect(() => {
|
|
9637
11552
|
if (!control._state.mount) {
|
|
9638
11553
|
control._setValid();
|
|
9639
11554
|
control._state.mount = true;
|
|
@@ -9650,8 +11565,8 @@ function useForm(props = {}) {
|
|
|
9650
11565
|
|
|
9651
11566
|
// ../../components/ui/Form.tsx
|
|
9652
11567
|
import { useTranslations as useTranslations8 } from "next-intl";
|
|
9653
|
-
import { jsx as
|
|
9654
|
-
var FormConfigContext =
|
|
11568
|
+
import { jsx as jsx48, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
11569
|
+
var FormConfigContext = React39.createContext({ size: "md" });
|
|
9655
11570
|
var FormWrapper = ({
|
|
9656
11571
|
children,
|
|
9657
11572
|
onSubmit,
|
|
@@ -9664,24 +11579,24 @@ var FormWrapper = ({
|
|
|
9664
11579
|
const methods = useForm({
|
|
9665
11580
|
defaultValues: initialValues
|
|
9666
11581
|
});
|
|
9667
|
-
|
|
11582
|
+
React39.useEffect(() => {
|
|
9668
11583
|
if (initialValues) {
|
|
9669
11584
|
methods.reset(initialValues);
|
|
9670
11585
|
}
|
|
9671
11586
|
}, [JSON.stringify(initialValues)]);
|
|
9672
11587
|
const { validationSchema: _, ...formProps } = props;
|
|
9673
|
-
return /* @__PURE__ */
|
|
11588
|
+
return /* @__PURE__ */ jsx48(FormProvider, { ...methods, children: /* @__PURE__ */ jsx48(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx48("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
|
|
9674
11589
|
};
|
|
9675
11590
|
var Form = FormWrapper;
|
|
9676
|
-
var FormFieldContext =
|
|
11591
|
+
var FormFieldContext = React39.createContext({});
|
|
9677
11592
|
var FormField = ({
|
|
9678
11593
|
...props
|
|
9679
11594
|
}) => {
|
|
9680
|
-
return /* @__PURE__ */
|
|
11595
|
+
return /* @__PURE__ */ jsx48(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx48(Controller, { ...props }) });
|
|
9681
11596
|
};
|
|
9682
11597
|
var useFormField = () => {
|
|
9683
|
-
const fieldContext =
|
|
9684
|
-
const itemContext =
|
|
11598
|
+
const fieldContext = React39.useContext(FormFieldContext);
|
|
11599
|
+
const itemContext = React39.useContext(FormItemContext);
|
|
9685
11600
|
const { getFieldState, formState } = useFormContext();
|
|
9686
11601
|
if (!fieldContext) {
|
|
9687
11602
|
try {
|
|
@@ -9702,22 +11617,22 @@ var useFormField = () => {
|
|
|
9702
11617
|
...fieldState
|
|
9703
11618
|
};
|
|
9704
11619
|
};
|
|
9705
|
-
var FormItemContext =
|
|
9706
|
-
var FormItem =
|
|
9707
|
-
const id =
|
|
9708
|
-
return /* @__PURE__ */
|
|
11620
|
+
var FormItemContext = React39.createContext({});
|
|
11621
|
+
var FormItem = React39.forwardRef(({ className, ...props }, ref) => {
|
|
11622
|
+
const id = React39.useId();
|
|
11623
|
+
return /* @__PURE__ */ jsx48(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx48("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
9709
11624
|
});
|
|
9710
11625
|
FormItem.displayName = "FormItem";
|
|
9711
|
-
var FormLabel =
|
|
11626
|
+
var FormLabel = React39.forwardRef(({ className, ...props }, ref) => {
|
|
9712
11627
|
const { error, formItemId } = useFormField();
|
|
9713
|
-
const config =
|
|
11628
|
+
const config = React39.useContext(FormConfigContext);
|
|
9714
11629
|
const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
|
|
9715
|
-
return /* @__PURE__ */
|
|
11630
|
+
return /* @__PURE__ */ jsx48(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props });
|
|
9716
11631
|
});
|
|
9717
11632
|
FormLabel.displayName = "FormLabel";
|
|
9718
|
-
var FormControl =
|
|
11633
|
+
var FormControl = React39.forwardRef(({ ...props }, ref) => {
|
|
9719
11634
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
9720
|
-
return /* @__PURE__ */
|
|
11635
|
+
return /* @__PURE__ */ jsx48(
|
|
9721
11636
|
"div",
|
|
9722
11637
|
{
|
|
9723
11638
|
ref,
|
|
@@ -9729,37 +11644,37 @@ var FormControl = React32.forwardRef(({ ...props }, ref) => {
|
|
|
9729
11644
|
);
|
|
9730
11645
|
});
|
|
9731
11646
|
FormControl.displayName = "FormControl";
|
|
9732
|
-
var FormDescription =
|
|
11647
|
+
var FormDescription = React39.forwardRef(({ className, ...props }, ref) => {
|
|
9733
11648
|
const { formDescriptionId } = useFormField();
|
|
9734
|
-
return /* @__PURE__ */
|
|
11649
|
+
return /* @__PURE__ */ jsx48("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
|
|
9735
11650
|
});
|
|
9736
11651
|
FormDescription.displayName = "FormDescription";
|
|
9737
|
-
var FormMessage =
|
|
11652
|
+
var FormMessage = React39.forwardRef(({ className, children, ...props }, ref) => {
|
|
9738
11653
|
const { error, formMessageId } = useFormField();
|
|
9739
11654
|
const body = error ? String(error?.message) : children;
|
|
9740
11655
|
if (!body) {
|
|
9741
11656
|
return null;
|
|
9742
11657
|
}
|
|
9743
|
-
return /* @__PURE__ */
|
|
11658
|
+
return /* @__PURE__ */ jsx48("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
|
|
9744
11659
|
});
|
|
9745
11660
|
FormMessage.displayName = "FormMessage";
|
|
9746
|
-
var FormInput =
|
|
11661
|
+
var FormInput = React39.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ jsx48(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx48(
|
|
9747
11662
|
FormField,
|
|
9748
11663
|
{
|
|
9749
11664
|
name,
|
|
9750
|
-
render: ({ field }) => /* @__PURE__ */
|
|
9751
|
-
/* @__PURE__ */
|
|
9752
|
-
/* @__PURE__ */
|
|
11665
|
+
render: ({ field }) => /* @__PURE__ */ jsxs42(FormItem, { children: [
|
|
11666
|
+
/* @__PURE__ */ jsx48(FormControl, { children: /* @__PURE__ */ jsx48(Input_default, { size: props.size ?? size, ...field, ...props }) }),
|
|
11667
|
+
/* @__PURE__ */ jsx48(FormMessage, {})
|
|
9753
11668
|
] })
|
|
9754
11669
|
}
|
|
9755
11670
|
) }));
|
|
9756
11671
|
FormInput.displayName = "FormInput";
|
|
9757
|
-
var FormCheckbox =
|
|
11672
|
+
var FormCheckbox = React39.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ jsx48(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx48(
|
|
9758
11673
|
FormField,
|
|
9759
11674
|
{
|
|
9760
11675
|
name,
|
|
9761
|
-
render: ({ field }) => /* @__PURE__ */
|
|
9762
|
-
/* @__PURE__ */
|
|
11676
|
+
render: ({ field }) => /* @__PURE__ */ jsxs42(FormItem, { children: [
|
|
11677
|
+
/* @__PURE__ */ jsx48(FormControl, { children: /* @__PURE__ */ jsx48(
|
|
9763
11678
|
Checkbox,
|
|
9764
11679
|
{
|
|
9765
11680
|
ref,
|
|
@@ -9773,24 +11688,24 @@ var FormCheckbox = React32.forwardRef(({ name, ...props }, ref) => /* @__PURE__
|
|
|
9773
11688
|
...props
|
|
9774
11689
|
}
|
|
9775
11690
|
) }),
|
|
9776
|
-
/* @__PURE__ */
|
|
11691
|
+
/* @__PURE__ */ jsx48(FormMessage, {})
|
|
9777
11692
|
] })
|
|
9778
11693
|
}
|
|
9779
11694
|
) }));
|
|
9780
11695
|
FormCheckbox.displayName = "FormCheckbox";
|
|
9781
|
-
var FormActions =
|
|
11696
|
+
var FormActions = React39.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
|
|
9782
11697
|
FormActions.displayName = "FormActions";
|
|
9783
|
-
var FormSubmitButton =
|
|
11698
|
+
var FormSubmitButton = React39.forwardRef(({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ jsx48(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx48(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) }));
|
|
9784
11699
|
FormSubmitButton.displayName = "FormSubmitButton";
|
|
9785
11700
|
|
|
9786
11701
|
// ../../components/ui/NotificationModal.tsx
|
|
9787
11702
|
import { ExternalLink } from "lucide-react";
|
|
9788
11703
|
import { useTranslations as useTranslations9 } from "next-intl";
|
|
9789
|
-
import { jsx as
|
|
11704
|
+
import { jsx as jsx49, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
9790
11705
|
function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
|
|
9791
11706
|
const t = useTranslations9("Common");
|
|
9792
11707
|
if (!notification) return null;
|
|
9793
|
-
const
|
|
11708
|
+
const formatTime3 = (dateString) => {
|
|
9794
11709
|
const date = new Date(dateString);
|
|
9795
11710
|
return date.toLocaleString(void 0, {
|
|
9796
11711
|
year: "numeric",
|
|
@@ -9807,26 +11722,26 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
|
|
|
9807
11722
|
onClose();
|
|
9808
11723
|
}
|
|
9809
11724
|
};
|
|
9810
|
-
return /* @__PURE__ */
|
|
11725
|
+
return /* @__PURE__ */ jsx49(
|
|
9811
11726
|
Modal_default,
|
|
9812
11727
|
{
|
|
9813
11728
|
isOpen,
|
|
9814
11729
|
onClose,
|
|
9815
11730
|
title: titleText || t("notifications"),
|
|
9816
11731
|
size: "md",
|
|
9817
|
-
children: /* @__PURE__ */
|
|
9818
|
-
/* @__PURE__ */
|
|
9819
|
-
/* @__PURE__ */
|
|
11732
|
+
children: /* @__PURE__ */ jsxs43("div", { className: "space-y-4", children: [
|
|
11733
|
+
/* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
|
|
11734
|
+
/* @__PURE__ */ jsx49("div", { className: cn(
|
|
9820
11735
|
"w-2 h-2 rounded-full",
|
|
9821
11736
|
!notification.is_read ? "bg-primary" : "bg-border"
|
|
9822
11737
|
) }),
|
|
9823
|
-
/* @__PURE__ */
|
|
11738
|
+
/* @__PURE__ */ jsx49("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
|
|
9824
11739
|
] }),
|
|
9825
|
-
notification.title && /* @__PURE__ */
|
|
9826
|
-
notification.body && /* @__PURE__ */
|
|
9827
|
-
/* @__PURE__ */
|
|
9828
|
-
/* @__PURE__ */
|
|
9829
|
-
hasLink && /* @__PURE__ */
|
|
11740
|
+
notification.title && /* @__PURE__ */ jsx49("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
|
|
11741
|
+
notification.body && /* @__PURE__ */ jsx49("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
|
|
11742
|
+
/* @__PURE__ */ jsx49("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
|
|
11743
|
+
/* @__PURE__ */ jsxs43("div", { className: "flex gap-2 justify-end pt-2", children: [
|
|
11744
|
+
hasLink && /* @__PURE__ */ jsxs43(
|
|
9830
11745
|
Button_default,
|
|
9831
11746
|
{
|
|
9832
11747
|
variant: "primary",
|
|
@@ -9834,12 +11749,12 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
|
|
|
9834
11749
|
onClick: handleLinkClick,
|
|
9835
11750
|
className: "gap-2",
|
|
9836
11751
|
children: [
|
|
9837
|
-
/* @__PURE__ */
|
|
11752
|
+
/* @__PURE__ */ jsx49(ExternalLink, { className: "w-4 h-4" }),
|
|
9838
11753
|
openLinkText || t("openLink")
|
|
9839
11754
|
]
|
|
9840
11755
|
}
|
|
9841
11756
|
),
|
|
9842
|
-
/* @__PURE__ */
|
|
11757
|
+
/* @__PURE__ */ jsx49(
|
|
9843
11758
|
Button_default,
|
|
9844
11759
|
{
|
|
9845
11760
|
variant: "ghost",
|
|
@@ -9861,10 +11776,10 @@ import { usePathname } from "next/navigation";
|
|
|
9861
11776
|
import { Phone } from "lucide-react";
|
|
9862
11777
|
|
|
9863
11778
|
// ../../node_modules/react-icons/lib/iconBase.mjs
|
|
9864
|
-
import
|
|
11779
|
+
import React41 from "react";
|
|
9865
11780
|
|
|
9866
11781
|
// ../../node_modules/react-icons/lib/iconContext.mjs
|
|
9867
|
-
import
|
|
11782
|
+
import React40 from "react";
|
|
9868
11783
|
var DefaultContext = {
|
|
9869
11784
|
color: void 0,
|
|
9870
11785
|
size: void 0,
|
|
@@ -9872,7 +11787,7 @@ var DefaultContext = {
|
|
|
9872
11787
|
style: void 0,
|
|
9873
11788
|
attr: void 0
|
|
9874
11789
|
};
|
|
9875
|
-
var IconContext =
|
|
11790
|
+
var IconContext = React40.createContext && /* @__PURE__ */ React40.createContext(DefaultContext);
|
|
9876
11791
|
|
|
9877
11792
|
// ../../node_modules/react-icons/lib/iconBase.mjs
|
|
9878
11793
|
var _excluded = ["attr", "size", "title"];
|
|
@@ -9961,12 +11876,12 @@ function _toPrimitive(t, r) {
|
|
|
9961
11876
|
return ("string" === r ? String : Number)(t);
|
|
9962
11877
|
}
|
|
9963
11878
|
function Tree2Element(tree) {
|
|
9964
|
-
return tree && tree.map((node, i) => /* @__PURE__ */
|
|
11879
|
+
return tree && tree.map((node, i) => /* @__PURE__ */ React41.createElement(node.tag, _objectSpread({
|
|
9965
11880
|
key: i
|
|
9966
11881
|
}, node.attr), Tree2Element(node.child)));
|
|
9967
11882
|
}
|
|
9968
11883
|
function GenIcon(data) {
|
|
9969
|
-
return (props) => /* @__PURE__ */
|
|
11884
|
+
return (props) => /* @__PURE__ */ React41.createElement(IconBase, _extends({
|
|
9970
11885
|
attr: _objectSpread({}, data.attr)
|
|
9971
11886
|
}, props), Tree2Element(data.child));
|
|
9972
11887
|
}
|
|
@@ -9981,7 +11896,7 @@ function IconBase(props) {
|
|
|
9981
11896
|
var className;
|
|
9982
11897
|
if (conf.className) className = conf.className;
|
|
9983
11898
|
if (props.className) className = (className ? className + " " : "") + props.className;
|
|
9984
|
-
return /* @__PURE__ */
|
|
11899
|
+
return /* @__PURE__ */ React41.createElement("svg", _extends({
|
|
9985
11900
|
stroke: "currentColor",
|
|
9986
11901
|
fill: "currentColor",
|
|
9987
11902
|
strokeWidth: "0"
|
|
@@ -9993,9 +11908,9 @@ function IconBase(props) {
|
|
|
9993
11908
|
height: computedSize,
|
|
9994
11909
|
width: computedSize,
|
|
9995
11910
|
xmlns: "http://www.w3.org/2000/svg"
|
|
9996
|
-
}), title && /* @__PURE__ */
|
|
11911
|
+
}), title && /* @__PURE__ */ React41.createElement("title", null, title), props.children);
|
|
9997
11912
|
};
|
|
9998
|
-
return IconContext !== void 0 ? /* @__PURE__ */
|
|
11913
|
+
return IconContext !== void 0 ? /* @__PURE__ */ React41.createElement(IconContext.Consumer, null, (conf) => elem(conf)) : elem(DefaultContext);
|
|
9999
11914
|
}
|
|
10000
11915
|
|
|
10001
11916
|
// ../../node_modules/react-icons/fa/index.mjs
|
|
@@ -10009,9 +11924,9 @@ function SiZalo(props) {
|
|
|
10009
11924
|
}
|
|
10010
11925
|
|
|
10011
11926
|
// ../../components/ui/FloatingContacts.tsx
|
|
10012
|
-
import { jsx as
|
|
11927
|
+
import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
10013
11928
|
function MessengerIcon(props) {
|
|
10014
|
-
return /* @__PURE__ */
|
|
11929
|
+
return /* @__PURE__ */ jsx50("svg", { viewBox: "0 0 24 24", width: 24, height: 24, "aria-hidden": "true", ...props, children: /* @__PURE__ */ jsx50(
|
|
10015
11930
|
"path",
|
|
10016
11931
|
{
|
|
10017
11932
|
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",
|
|
@@ -10020,10 +11935,10 @@ function MessengerIcon(props) {
|
|
|
10020
11935
|
) });
|
|
10021
11936
|
}
|
|
10022
11937
|
function ZaloIcon(props) {
|
|
10023
|
-
return /* @__PURE__ */
|
|
11938
|
+
return /* @__PURE__ */ jsx50(SiZalo, { size: 20, ...props });
|
|
10024
11939
|
}
|
|
10025
11940
|
function InstagramIcon(props) {
|
|
10026
|
-
return /* @__PURE__ */
|
|
11941
|
+
return /* @__PURE__ */ jsx50(FaInstagram, { size: 20, ...props });
|
|
10027
11942
|
}
|
|
10028
11943
|
function FloatingContacts({ className }) {
|
|
10029
11944
|
const pathname = usePathname();
|
|
@@ -10058,8 +11973,8 @@ function FloatingContacts({ className }) {
|
|
|
10058
11973
|
external: true
|
|
10059
11974
|
}
|
|
10060
11975
|
];
|
|
10061
|
-
return /* @__PURE__ */
|
|
10062
|
-
/* @__PURE__ */
|
|
11976
|
+
return /* @__PURE__ */ jsxs44("div", { className: cn("fixed bottom-6 right-4 z-[100000]", "flex flex-col items-end gap-3", className), "aria-label": "Quick contacts", children: [
|
|
11977
|
+
/* @__PURE__ */ jsx50(
|
|
10063
11978
|
Link2,
|
|
10064
11979
|
{
|
|
10065
11980
|
href: `tel:${hotline.replace(/\D/g, "")}`,
|
|
@@ -10070,10 +11985,10 @@ function FloatingContacts({ className }) {
|
|
|
10070
11985
|
"hover:scale-105 active:scale-95 transition-transform",
|
|
10071
11986
|
"bg-[#22c55e]"
|
|
10072
11987
|
),
|
|
10073
|
-
children: /* @__PURE__ */
|
|
11988
|
+
children: /* @__PURE__ */ jsx50(Phone, { className: "w-6 h-6" })
|
|
10074
11989
|
}
|
|
10075
11990
|
),
|
|
10076
|
-
moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */
|
|
11991
|
+
moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ jsx50(
|
|
10077
11992
|
Link2,
|
|
10078
11993
|
{
|
|
10079
11994
|
href,
|
|
@@ -10085,7 +12000,7 @@ function FloatingContacts({ className }) {
|
|
|
10085
12000
|
"hover:scale-105 active:scale-95 transition-transform",
|
|
10086
12001
|
bg
|
|
10087
12002
|
),
|
|
10088
|
-
children: /* @__PURE__ */
|
|
12003
|
+
children: /* @__PURE__ */ jsx50(Icon, { className: "w-6 h-6" })
|
|
10089
12004
|
},
|
|
10090
12005
|
key
|
|
10091
12006
|
))
|
|
@@ -10094,7 +12009,7 @@ function FloatingContacts({ className }) {
|
|
|
10094
12009
|
|
|
10095
12010
|
// ../../components/ui/AccessDenied.tsx
|
|
10096
12011
|
import { Lock, ShieldAlert, Ban } from "lucide-react";
|
|
10097
|
-
import { jsx as
|
|
12012
|
+
import { jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
10098
12013
|
var VARIANT_STYLES = {
|
|
10099
12014
|
destructive: { bg: "bg-destructive/5", border: "border-destructive/20", text: "text-destructive" },
|
|
10100
12015
|
warning: { bg: "bg-warning/5", border: "border-warning/20", text: "text-warning" },
|
|
@@ -10115,32 +12030,32 @@ function AccessDenied({
|
|
|
10115
12030
|
}) {
|
|
10116
12031
|
const styles = VARIANT_STYLES[variant];
|
|
10117
12032
|
const UsedIcon = Icon || DEFAULT_ICONS[variant];
|
|
10118
|
-
return /* @__PURE__ */
|
|
10119
|
-
/* @__PURE__ */
|
|
10120
|
-
/* @__PURE__ */
|
|
10121
|
-
/* @__PURE__ */
|
|
10122
|
-
/* @__PURE__ */
|
|
12033
|
+
return /* @__PURE__ */ jsx51(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ jsxs45("div", { className: "flex flex-col items-center gap-4", children: [
|
|
12034
|
+
/* @__PURE__ */ jsx51("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ jsx51(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
|
|
12035
|
+
/* @__PURE__ */ jsxs45("div", { children: [
|
|
12036
|
+
/* @__PURE__ */ jsx51("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
|
|
12037
|
+
/* @__PURE__ */ jsx51("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
|
|
10123
12038
|
] }),
|
|
10124
|
-
children && /* @__PURE__ */
|
|
12039
|
+
children && /* @__PURE__ */ jsx51("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
|
|
10125
12040
|
] }) });
|
|
10126
12041
|
}
|
|
10127
12042
|
|
|
10128
12043
|
// ../../components/ui/ThemeToggleHeadless.tsx
|
|
10129
12044
|
import { Moon, Sun, Monitor } from "lucide-react";
|
|
10130
|
-
import { useEffect as
|
|
10131
|
-
import { createPortal as
|
|
10132
|
-
import { Fragment as
|
|
12045
|
+
import { useEffect as useEffect20, useRef as useRef11, useState as useState32 } from "react";
|
|
12046
|
+
import { createPortal as createPortal10 } from "react-dom";
|
|
12047
|
+
import { Fragment as Fragment16, jsx as jsx52, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
10133
12048
|
function ThemeToggleHeadless({
|
|
10134
12049
|
theme,
|
|
10135
12050
|
onChange,
|
|
10136
12051
|
labels,
|
|
10137
12052
|
className
|
|
10138
12053
|
}) {
|
|
10139
|
-
const [isOpen, setIsOpen] =
|
|
10140
|
-
const [mounted, setMounted] =
|
|
12054
|
+
const [isOpen, setIsOpen] = useState32(false);
|
|
12055
|
+
const [mounted, setMounted] = useState32(false);
|
|
10141
12056
|
const triggerRef = useRef11(null);
|
|
10142
|
-
const [dropdownPosition, setDropdownPosition] =
|
|
10143
|
-
|
|
12057
|
+
const [dropdownPosition, setDropdownPosition] = useState32(null);
|
|
12058
|
+
useEffect20(() => setMounted(true), []);
|
|
10144
12059
|
const themes = [
|
|
10145
12060
|
{ value: "light", label: labels?.light ?? "Light", icon: Sun },
|
|
10146
12061
|
{ value: "dark", label: labels?.dark ?? "Dark", icon: Moon },
|
|
@@ -10158,8 +12073,8 @@ function ThemeToggleHeadless({
|
|
|
10158
12073
|
const top = rect.bottom + scrollTop + 8;
|
|
10159
12074
|
return { top, left, width };
|
|
10160
12075
|
};
|
|
10161
|
-
return /* @__PURE__ */
|
|
10162
|
-
/* @__PURE__ */
|
|
12076
|
+
return /* @__PURE__ */ jsxs46("div", { className: cn("relative", className), children: [
|
|
12077
|
+
/* @__PURE__ */ jsx52(
|
|
10163
12078
|
Button_default,
|
|
10164
12079
|
{
|
|
10165
12080
|
variant: "ghost",
|
|
@@ -10177,25 +12092,25 @@ function ThemeToggleHeadless({
|
|
|
10177
12092
|
"aria-haspopup": "menu",
|
|
10178
12093
|
"aria-expanded": isOpen,
|
|
10179
12094
|
"aria-label": labels?.heading ?? "Theme",
|
|
10180
|
-
children: /* @__PURE__ */
|
|
12095
|
+
children: /* @__PURE__ */ jsx52(CurrentIcon, { className: "h-5 w-5" })
|
|
10181
12096
|
}
|
|
10182
12097
|
),
|
|
10183
|
-
isOpen && /* @__PURE__ */
|
|
10184
|
-
typeof window !== "undefined" &&
|
|
10185
|
-
typeof window !== "undefined" && dropdownPosition &&
|
|
10186
|
-
/* @__PURE__ */
|
|
12098
|
+
isOpen && /* @__PURE__ */ jsxs46(Fragment16, { children: [
|
|
12099
|
+
typeof window !== "undefined" && createPortal10(/* @__PURE__ */ jsx52("div", { className: "fixed inset-0 z-[9998]", onClick: () => setIsOpen(false) }), document.body),
|
|
12100
|
+
typeof window !== "undefined" && dropdownPosition && createPortal10(
|
|
12101
|
+
/* @__PURE__ */ jsx52(
|
|
10187
12102
|
"div",
|
|
10188
12103
|
{
|
|
10189
12104
|
className: "z-[9999] bg-card border border-border rounded-lg shadow-lg overflow-hidden",
|
|
10190
12105
|
style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
|
|
10191
12106
|
onMouseDown: (e) => e.stopPropagation(),
|
|
10192
12107
|
role: "menu",
|
|
10193
|
-
children: /* @__PURE__ */
|
|
10194
|
-
/* @__PURE__ */
|
|
12108
|
+
children: /* @__PURE__ */ jsxs46("div", { className: "p-2", children: [
|
|
12109
|
+
/* @__PURE__ */ jsx52("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
|
|
10195
12110
|
themes.map((opt) => {
|
|
10196
12111
|
const Icon = opt.icon;
|
|
10197
12112
|
const active = theme === opt.value;
|
|
10198
|
-
return /* @__PURE__ */
|
|
12113
|
+
return /* @__PURE__ */ jsxs46(
|
|
10199
12114
|
Button_default,
|
|
10200
12115
|
{
|
|
10201
12116
|
variant: "ghost",
|
|
@@ -10211,9 +12126,9 @@ function ThemeToggleHeadless({
|
|
|
10211
12126
|
role: "menuitemradio",
|
|
10212
12127
|
"aria-checked": active,
|
|
10213
12128
|
children: [
|
|
10214
|
-
/* @__PURE__ */
|
|
10215
|
-
/* @__PURE__ */
|
|
10216
|
-
active && /* @__PURE__ */
|
|
12129
|
+
/* @__PURE__ */ jsx52(Icon, { className: "h-4 w-4" }),
|
|
12130
|
+
/* @__PURE__ */ jsx52("span", { className: "flex-1 text-left", children: opt.label }),
|
|
12131
|
+
active && /* @__PURE__ */ jsx52("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
10217
12132
|
]
|
|
10218
12133
|
},
|
|
10219
12134
|
opt.value
|
|
@@ -10229,10 +12144,10 @@ function ThemeToggleHeadless({
|
|
|
10229
12144
|
}
|
|
10230
12145
|
|
|
10231
12146
|
// ../../components/ui/LanguageSwitcherHeadless.tsx
|
|
10232
|
-
import { useRef as useRef12, useState as
|
|
10233
|
-
import { createPortal as
|
|
12147
|
+
import { useRef as useRef12, useState as useState33 } from "react";
|
|
12148
|
+
import { createPortal as createPortal11 } from "react-dom";
|
|
10234
12149
|
import { Globe } from "lucide-react";
|
|
10235
|
-
import { Fragment as
|
|
12150
|
+
import { Fragment as Fragment17, jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
10236
12151
|
function LanguageSwitcherHeadless({
|
|
10237
12152
|
locales,
|
|
10238
12153
|
currentLocale,
|
|
@@ -10240,8 +12155,8 @@ function LanguageSwitcherHeadless({
|
|
|
10240
12155
|
labels,
|
|
10241
12156
|
className
|
|
10242
12157
|
}) {
|
|
10243
|
-
const [isOpen, setIsOpen] =
|
|
10244
|
-
const [dropdownPosition, setDropdownPosition] =
|
|
12158
|
+
const [isOpen, setIsOpen] = useState33(false);
|
|
12159
|
+
const [dropdownPosition, setDropdownPosition] = useState33(null);
|
|
10245
12160
|
const triggerButtonRef = useRef12(null);
|
|
10246
12161
|
const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
|
|
10247
12162
|
const calculatePosition = () => {
|
|
@@ -10254,8 +12169,8 @@ function LanguageSwitcherHeadless({
|
|
|
10254
12169
|
const top = rect.bottom + scrollTop + 8;
|
|
10255
12170
|
return { top, left, width };
|
|
10256
12171
|
};
|
|
10257
|
-
return /* @__PURE__ */
|
|
10258
|
-
/* @__PURE__ */
|
|
12172
|
+
return /* @__PURE__ */ jsxs47("div", { className: cn("relative", className), children: [
|
|
12173
|
+
/* @__PURE__ */ jsx53(
|
|
10259
12174
|
Button_default,
|
|
10260
12175
|
{
|
|
10261
12176
|
variant: "ghost",
|
|
@@ -10274,22 +12189,22 @@ function LanguageSwitcherHeadless({
|
|
|
10274
12189
|
"aria-expanded": isOpen,
|
|
10275
12190
|
"aria-label": labels?.heading ?? "Language",
|
|
10276
12191
|
title: labels?.heading ?? "Language",
|
|
10277
|
-
children: /* @__PURE__ */
|
|
12192
|
+
children: /* @__PURE__ */ jsx53(Globe, { className: "h-5 w-5" })
|
|
10278
12193
|
}
|
|
10279
12194
|
),
|
|
10280
|
-
isOpen && /* @__PURE__ */
|
|
10281
|
-
typeof window !== "undefined" &&
|
|
10282
|
-
typeof window !== "undefined" && dropdownPosition &&
|
|
10283
|
-
/* @__PURE__ */
|
|
12195
|
+
isOpen && /* @__PURE__ */ jsxs47(Fragment17, { children: [
|
|
12196
|
+
typeof window !== "undefined" && createPortal11(/* @__PURE__ */ jsx53("div", { className: "fixed inset-0 z-[9998]", onClick: () => setIsOpen(false) }), document.body),
|
|
12197
|
+
typeof window !== "undefined" && dropdownPosition && createPortal11(
|
|
12198
|
+
/* @__PURE__ */ jsx53(
|
|
10284
12199
|
"div",
|
|
10285
12200
|
{
|
|
10286
12201
|
className: "z-[9999] bg-card border border-border rounded-lg shadow-lg overflow-hidden",
|
|
10287
12202
|
style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
|
|
10288
12203
|
onMouseDown: (e) => e.stopPropagation(),
|
|
10289
12204
|
role: "menu",
|
|
10290
|
-
children: /* @__PURE__ */
|
|
10291
|
-
/* @__PURE__ */
|
|
10292
|
-
locales.map((language) => /* @__PURE__ */
|
|
12205
|
+
children: /* @__PURE__ */ jsxs47("div", { className: "p-2", children: [
|
|
12206
|
+
/* @__PURE__ */ jsx53("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
|
|
12207
|
+
locales.map((language) => /* @__PURE__ */ jsxs47(
|
|
10293
12208
|
Button_default,
|
|
10294
12209
|
{
|
|
10295
12210
|
variant: "ghost",
|
|
@@ -10302,9 +12217,9 @@ function LanguageSwitcherHeadless({
|
|
|
10302
12217
|
role: "menuitemradio",
|
|
10303
12218
|
"aria-checked": currentLocale === language.code,
|
|
10304
12219
|
children: [
|
|
10305
|
-
language.flag && /* @__PURE__ */
|
|
10306
|
-
/* @__PURE__ */
|
|
10307
|
-
currentLocale === language.code && /* @__PURE__ */
|
|
12220
|
+
language.flag && /* @__PURE__ */ jsx53("span", { className: "text-lg", children: language.flag }),
|
|
12221
|
+
/* @__PURE__ */ jsx53("span", { className: "flex-1 text-left", children: language.name }),
|
|
12222
|
+
currentLocale === language.code && /* @__PURE__ */ jsx53("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
10308
12223
|
]
|
|
10309
12224
|
},
|
|
10310
12225
|
language.code
|
|
@@ -10460,12 +12375,14 @@ export {
|
|
|
10460
12375
|
Breadcrumb_default as Breadcrumb,
|
|
10461
12376
|
Button_default as Button,
|
|
10462
12377
|
ButtonLoading,
|
|
12378
|
+
Calendar2 as Calendar,
|
|
10463
12379
|
Card_default as Card,
|
|
10464
12380
|
Carousel,
|
|
10465
12381
|
CategoryTreeSelect,
|
|
10466
12382
|
Checkbox,
|
|
10467
12383
|
CircularProgress,
|
|
10468
12384
|
ClientOnly,
|
|
12385
|
+
ColorPicker,
|
|
10469
12386
|
Combobox,
|
|
10470
12387
|
CompactPagination,
|
|
10471
12388
|
DataTable_default as DataTable,
|
|
@@ -10491,6 +12408,8 @@ export {
|
|
|
10491
12408
|
FormSubmitButton,
|
|
10492
12409
|
GlobalLoading,
|
|
10493
12410
|
GradientBadge,
|
|
12411
|
+
Grid_default as Grid,
|
|
12412
|
+
GridItem,
|
|
10494
12413
|
ImageUpload,
|
|
10495
12414
|
InlineLoading,
|
|
10496
12415
|
Input_default as Input,
|
|
@@ -10498,6 +12417,8 @@ export {
|
|
|
10498
12417
|
Label,
|
|
10499
12418
|
LanguageSwitcherHeadless as LanguageSwitcher,
|
|
10500
12419
|
LanguageSwitcherHeadless,
|
|
12420
|
+
List_default as List,
|
|
12421
|
+
ListItem,
|
|
10501
12422
|
LoadingBar,
|
|
10502
12423
|
LoadingDots,
|
|
10503
12424
|
LoadingProgress,
|
|
@@ -10556,11 +12477,15 @@ export {
|
|
|
10556
12477
|
Textarea_default as Textarea,
|
|
10557
12478
|
ThemeToggleHeadless as ThemeToggle,
|
|
10558
12479
|
ThemeToggleHeadless,
|
|
12480
|
+
TimePicker,
|
|
12481
|
+
Timeline_default as Timeline,
|
|
12482
|
+
TimelineItem,
|
|
10559
12483
|
Toast_default as ToastProvider,
|
|
10560
12484
|
Tooltip,
|
|
10561
12485
|
VARIANT_STYLES_ALERT,
|
|
10562
12486
|
VARIANT_STYLES_BTN,
|
|
10563
12487
|
VerticalTabs,
|
|
12488
|
+
Watermark_default as Watermark,
|
|
10564
12489
|
cn,
|
|
10565
12490
|
getUnderverseMessages,
|
|
10566
12491
|
underverseMessages,
|