@underverse-ui/underverse 0.2.65 → 0.2.67

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 CHANGED
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
33
  AccessDenied: () => AccessDenied,
34
34
  Alert: () => Alert_default,
35
35
  AreaChart: () => AreaChart,
@@ -64,6 +64,17 @@ __export(src_exports, {
64
64
  FallingIcons: () => FallingIcons,
65
65
  FloatingContacts: () => FloatingContacts,
66
66
  ForceInternalTranslationsProvider: () => ForceInternalTranslationsProvider,
67
+ Form: () => Form,
68
+ FormActions: () => FormActions,
69
+ FormCheckbox: () => FormCheckbox,
70
+ FormControl: () => FormControl,
71
+ FormDescription: () => FormDescription,
72
+ FormField: () => FormField,
73
+ FormInput: () => FormInput,
74
+ FormItem: () => FormItem,
75
+ FormLabel: () => FormLabel,
76
+ FormMessage: () => FormMessage,
77
+ FormSubmitButton: () => FormSubmitButton,
67
78
  GaugeChart: () => GaugeChart,
68
79
  GlobalLoading: () => GlobalLoading,
69
80
  GradientBadge: () => GradientBadge,
@@ -160,6 +171,7 @@ __export(src_exports, {
160
171
  injectAnimationStyles: () => injectAnimationStyles,
161
172
  shadcnAnimationStyles: () => shadcnAnimationStyles2,
162
173
  underverseMessages: () => underverseMessages,
174
+ useFormField: () => useFormField,
163
175
  useShadCNAnimations: () => useShadCNAnimations2,
164
176
  useSmartLocale: () => useSmartLocale,
165
177
  useSmartTranslations: () => useSmartTranslations,
@@ -169,7 +181,7 @@ __export(src_exports, {
169
181
  useUnderverseLocale: () => useUnderverseLocale,
170
182
  useUnderverseTranslations: () => useUnderverseTranslations
171
183
  });
172
- module.exports = __toCommonJS(src_exports);
184
+ module.exports = __toCommonJS(index_exports);
173
185
 
174
186
  // ../../components/ui/Button.tsx
175
187
  var import_react = require("react");
@@ -1463,7 +1475,7 @@ var NumberInput = (0, import_react3.forwardRef)(
1463
1475
  )
1464
1476
  }
1465
1477
  ),
1466
- showSteppers && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "absolute right-2 top-1/2 -translate-y-1/2 flex flex-col gap-0.5", children: [
1478
+ showSteppers && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "absolute right-4 top-1/2 -translate-y-[64%] flex flex-col gap-0.5", children: [
1467
1479
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1468
1480
  "button",
1469
1481
  {
@@ -9078,14 +9090,12 @@ function CategoryTreeSelect(props) {
9078
9090
  "div",
9079
9091
  {
9080
9092
  className: cn(
9081
- "relative flex items-center gap-2.5 px-3 py-2.5 transition-all duration-200",
9082
- "border-l-4 border-l-transparent",
9083
- // Parent level styling
9084
- isParent && "bg-muted/25 font-medium",
9093
+ "relative flex items-center gap-2.5 px-3 py-2.5 transition-all duration-200 rounded-lg",
9094
+ // Không phân biệt parent/child - đồng bộ màu
9085
9095
  !viewOnly && "cursor-pointer",
9086
- !viewOnly && !isSelected && "hover:bg-accent/60 hover:shadow-sm",
9087
- // Selected state
9088
- !viewOnly && isSelected && "bg-accent/30 border-l-primary shadow-sm"
9096
+ !viewOnly && !isSelected && "hover:bg-accent/50",
9097
+ // Selected state - đồng bộ cho tất cả
9098
+ !viewOnly && isSelected && "bg-accent/40"
9089
9099
  ),
9090
9100
  style: { paddingLeft: `${level * 1.25 + 0.75}rem` },
9091
9101
  children: [
@@ -13598,9 +13608,152 @@ function DataTable({
13598
13608
  }
13599
13609
  var DataTable_default = DataTable;
13600
13610
 
13611
+ // ../../components/ui/Form.tsx
13612
+ var React49 = __toESM(require("react"), 1);
13613
+ var import_react_hook_form = require("react-hook-form");
13614
+ var import_jsx_runtime58 = require("react/jsx-runtime");
13615
+ var FormConfigContext = React49.createContext({ size: "md" });
13616
+ var FormWrapper = ({
13617
+ children,
13618
+ onSubmit,
13619
+ initialValues,
13620
+ validationSchema,
13621
+ className,
13622
+ size = "md",
13623
+ ...props
13624
+ }) => {
13625
+ const methods = (0, import_react_hook_form.useForm)({
13626
+ defaultValues: initialValues
13627
+ });
13628
+ React49.useEffect(() => {
13629
+ if (initialValues) {
13630
+ methods.reset(initialValues);
13631
+ }
13632
+ }, [JSON.stringify(initialValues)]);
13633
+ const { validationSchema: _, ...formProps } = props;
13634
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_hook_form.FormProvider, { ...methods, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
13635
+ };
13636
+ var Form = FormWrapper;
13637
+ var FormFieldContext = React49.createContext({});
13638
+ var FormField = ({
13639
+ ...props
13640
+ }) => {
13641
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_hook_form.Controller, { ...props }) });
13642
+ };
13643
+ var useFormField = () => {
13644
+ const fieldContext = React49.useContext(FormFieldContext);
13645
+ const itemContext = React49.useContext(FormItemContext);
13646
+ const { getFieldState, formState } = (0, import_react_hook_form.useFormContext)();
13647
+ if (!fieldContext) {
13648
+ try {
13649
+ const t = useTranslations("Form");
13650
+ throw new Error(t("validation.mustBeUsedWithinForm"));
13651
+ } catch {
13652
+ throw new Error("useFormField must be used within FormField");
13653
+ }
13654
+ }
13655
+ const fieldState = getFieldState(fieldContext.name, formState);
13656
+ const { id } = itemContext;
13657
+ return {
13658
+ id,
13659
+ name: fieldContext.name,
13660
+ formItemId: `${id}-form-item`,
13661
+ formDescriptionId: `${id}-form-item-description`,
13662
+ formMessageId: `${id}-form-item-message`,
13663
+ ...fieldState
13664
+ };
13665
+ };
13666
+ var FormItemContext = React49.createContext({});
13667
+ var FormItem = React49.forwardRef(({ className, ...props }, ref) => {
13668
+ const id = React49.useId();
13669
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { ref, className: cn("space-y-2", className), ...props }) });
13670
+ });
13671
+ FormItem.displayName = "FormItem";
13672
+ var FormLabel = React49.forwardRef(
13673
+ ({ className, children, required, ...props }, ref) => {
13674
+ const { error, formItemId } = useFormField();
13675
+ const config = React49.useContext(FormConfigContext);
13676
+ const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
13677
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props, children: [
13678
+ children,
13679
+ required && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-destructive ml-1", children: "*" })
13680
+ ] });
13681
+ }
13682
+ );
13683
+ FormLabel.displayName = "FormLabel";
13684
+ var FormControl = React49.forwardRef(({ ...props }, ref) => {
13685
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
13686
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13687
+ "div",
13688
+ {
13689
+ ref,
13690
+ id: formItemId,
13691
+ "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`,
13692
+ "aria-invalid": !!error,
13693
+ ...props
13694
+ }
13695
+ );
13696
+ });
13697
+ FormControl.displayName = "FormControl";
13698
+ var FormDescription = React49.forwardRef(({ className, ...props }, ref) => {
13699
+ const { formDescriptionId } = useFormField();
13700
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
13701
+ });
13702
+ FormDescription.displayName = "FormDescription";
13703
+ var FormMessage = React49.forwardRef(({ className, children, ...props }, ref) => {
13704
+ const { error, formMessageId } = useFormField();
13705
+ const body = error ? String(error?.message) : children;
13706
+ if (!body) {
13707
+ return null;
13708
+ }
13709
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
13710
+ });
13711
+ FormMessage.displayName = "FormMessage";
13712
+ var FormInput = React49.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13713
+ FormField,
13714
+ {
13715
+ name,
13716
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(FormItem, { children: [
13717
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Input_default, { size: props.size ?? size, ...field, ...props }) }),
13718
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormMessage, {})
13719
+ ] })
13720
+ }
13721
+ ) }));
13722
+ FormInput.displayName = "FormInput";
13723
+ var FormCheckbox = React49.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13724
+ FormField,
13725
+ {
13726
+ name,
13727
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(FormItem, { children: [
13728
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13729
+ Checkbox,
13730
+ {
13731
+ ref,
13732
+ checked: field.value,
13733
+ onChange: (e) => field.onChange(e.target.checked),
13734
+ labelClassName: cn(
13735
+ // align label text size with inputs/buttons by form size
13736
+ size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
13737
+ props.labelClassName
13738
+ ),
13739
+ ...props
13740
+ }
13741
+ ) }),
13742
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormMessage, {})
13743
+ ] })
13744
+ }
13745
+ ) }));
13746
+ FormCheckbox.displayName = "FormCheckbox";
13747
+ var FormActions = React49.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
13748
+ FormActions.displayName = "FormActions";
13749
+ var FormSubmitButton = React49.forwardRef(
13750
+ ({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) })
13751
+ );
13752
+ FormSubmitButton.displayName = "FormSubmitButton";
13753
+
13601
13754
  // ../../components/ui/NotificationModal.tsx
13602
13755
  var import_lucide_react28 = require("lucide-react");
13603
- var import_jsx_runtime58 = require("react/jsx-runtime");
13756
+ var import_jsx_runtime59 = require("react/jsx-runtime");
13604
13757
  function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
13605
13758
  const t = useTranslations("Common");
13606
13759
  if (!notification) return null;
@@ -13621,20 +13774,20 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
13621
13774
  onClose();
13622
13775
  }
13623
13776
  };
13624
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Modal_default, { isOpen, onClose, title: titleText || t("notifications"), size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "space-y-4", children: [
13625
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
13626
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: cn("w-2 h-2 rounded-full", !notification.is_read ? "bg-primary" : "bg-border") }),
13627
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
13777
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Modal_default, { isOpen, onClose, title: titleText || t("notifications"), size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "space-y-4", children: [
13778
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
13779
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn("w-2 h-2 rounded-full", !notification.is_read ? "bg-primary" : "bg-border") }),
13780
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
13628
13781
  ] }),
13629
- notification.title && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
13630
- notification.body && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
13631
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
13632
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex gap-2 justify-end pt-2", children: [
13633
- hasLink && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Button_default, { variant: "primary", size: "sm", onClick: handleLinkClick, className: "gap-2", children: [
13634
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react28.ExternalLink, { className: "w-4 h-4" }),
13782
+ notification.title && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
13783
+ notification.body && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
13784
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
13785
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex gap-2 justify-end pt-2", children: [
13786
+ hasLink && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(Button_default, { variant: "primary", size: "sm", onClick: handleLinkClick, className: "gap-2", children: [
13787
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react28.ExternalLink, { className: "w-4 h-4" }),
13635
13788
  openLinkText || t("openLink")
13636
13789
  ] }),
13637
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
13790
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
13638
13791
  ] })
13639
13792
  ] }) });
13640
13793
  }
@@ -13644,9 +13797,9 @@ var NotificationModal_default = NotificationModal;
13644
13797
  var import_link2 = __toESM(require("next/link"), 1);
13645
13798
  var import_navigation = require("next/navigation");
13646
13799
  var import_lucide_react29 = require("lucide-react");
13647
- var import_jsx_runtime59 = require("react/jsx-runtime");
13800
+ var import_jsx_runtime60 = require("react/jsx-runtime");
13648
13801
  function MessengerIcon(props) {
13649
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 24 24", width: 24, height: 24, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13802
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("svg", { viewBox: "0 0 24 24", width: 24, height: 24, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
13650
13803
  "path",
13651
13804
  {
13652
13805
  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",
@@ -13655,7 +13808,7 @@ function MessengerIcon(props) {
13655
13808
  ) });
13656
13809
  }
13657
13810
  function ZaloIcon(props) {
13658
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 48 48", width: 20, height: 20, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13811
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("svg", { viewBox: "0 0 48 48", width: 20, height: 20, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
13659
13812
  "path",
13660
13813
  {
13661
13814
  fill: "white",
@@ -13664,7 +13817,7 @@ function ZaloIcon(props) {
13664
13817
  ) });
13665
13818
  }
13666
13819
  function InstagramIcon(props) {
13667
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 24 24", width: 20, height: 20, "aria-hidden": "true", fill: "white", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { d: "M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" }) });
13820
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("svg", { viewBox: "0 0 24 24", width: 20, height: 20, "aria-hidden": "true", fill: "white", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("path", { d: "M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" }) });
13668
13821
  }
13669
13822
  function FloatingContacts({ className }) {
13670
13823
  const pathname = (0, import_navigation.usePathname)();
@@ -13699,8 +13852,8 @@ function FloatingContacts({ className }) {
13699
13852
  external: true
13700
13853
  }
13701
13854
  ];
13702
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: cn("fixed bottom-6 right-4 z-100000", "flex flex-col items-end gap-3", className), "aria-label": "Quick contacts", children: [
13703
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13855
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: cn("fixed bottom-6 right-4 z-100000", "flex flex-col items-end gap-3", className), "aria-label": "Quick contacts", children: [
13856
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
13704
13857
  import_link2.default,
13705
13858
  {
13706
13859
  href: `tel:${hotline.replace(/\D/g, "")}`,
@@ -13711,10 +13864,10 @@ function FloatingContacts({ className }) {
13711
13864
  "hover:scale-105 active:scale-95 transition-transform",
13712
13865
  "bg-[#22c55e]"
13713
13866
  ),
13714
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react29.Phone, { className: "w-6 h-6" })
13867
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react29.Phone, { className: "w-6 h-6" })
13715
13868
  }
13716
13869
  ),
13717
- moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13870
+ moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
13718
13871
  import_link2.default,
13719
13872
  {
13720
13873
  href,
@@ -13726,7 +13879,7 @@ function FloatingContacts({ className }) {
13726
13879
  "hover:scale-105 active:scale-95 transition-transform",
13727
13880
  bg
13728
13881
  ),
13729
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Icon, { className: "w-6 h-6" })
13882
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { className: "w-6 h-6" })
13730
13883
  },
13731
13884
  key
13732
13885
  ))
@@ -13735,7 +13888,7 @@ function FloatingContacts({ className }) {
13735
13888
 
13736
13889
  // ../../components/ui/AccessDenied.tsx
13737
13890
  var import_lucide_react30 = require("lucide-react");
13738
- var import_jsx_runtime60 = require("react/jsx-runtime");
13891
+ var import_jsx_runtime61 = require("react/jsx-runtime");
13739
13892
  var VARIANT_STYLES = {
13740
13893
  destructive: { bg: "bg-destructive/5", border: "border-destructive/20", text: "text-destructive" },
13741
13894
  warning: { bg: "bg-warning/5", border: "border-warning/20", text: "text-warning" },
@@ -13756,13 +13909,13 @@ function AccessDenied({
13756
13909
  }) {
13757
13910
  const styles = VARIANT_STYLES[variant];
13758
13911
  const UsedIcon = Icon || DEFAULT_ICONS[variant];
13759
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
13760
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
13761
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
13762
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
13763
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
13912
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
13913
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
13914
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
13915
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
13916
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
13764
13917
  ] }),
13765
- children && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
13918
+ children && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
13766
13919
  ] }) });
13767
13920
  }
13768
13921
 
@@ -13770,7 +13923,7 @@ function AccessDenied({
13770
13923
  var import_lucide_react31 = require("lucide-react");
13771
13924
  var import_react33 = require("react");
13772
13925
  var import_react_dom7 = require("react-dom");
13773
- var import_jsx_runtime61 = require("react/jsx-runtime");
13926
+ var import_jsx_runtime62 = require("react/jsx-runtime");
13774
13927
  function ThemeToggleHeadless({
13775
13928
  theme,
13776
13929
  onChange,
@@ -13799,8 +13952,8 @@ function ThemeToggleHeadless({
13799
13952
  const top = rect.bottom + scrollTop + 8;
13800
13953
  return { top, left, width };
13801
13954
  };
13802
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: cn("relative", className), children: [
13803
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
13955
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cn("relative", className), children: [
13956
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
13804
13957
  Button_default,
13805
13958
  {
13806
13959
  variant: "ghost",
@@ -13818,25 +13971,25 @@ function ThemeToggleHeadless({
13818
13971
  "aria-haspopup": "menu",
13819
13972
  "aria-expanded": isOpen,
13820
13973
  "aria-label": labels?.heading ?? "Theme",
13821
- children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CurrentIcon, { className: "h-5 w-5" })
13974
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(CurrentIcon, { className: "h-5 w-5" })
13822
13975
  }
13823
13976
  ),
13824
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
13825
- typeof window !== "undefined" && (0, import_react_dom7.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
13977
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
13978
+ typeof window !== "undefined" && (0, import_react_dom7.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
13826
13979
  typeof window !== "undefined" && dropdownPosition && (0, import_react_dom7.createPortal)(
13827
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
13980
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
13828
13981
  "div",
13829
13982
  {
13830
13983
  className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
13831
13984
  style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
13832
13985
  onMouseDown: (e) => e.stopPropagation(),
13833
13986
  role: "menu",
13834
- children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "p-2", children: [
13835
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
13987
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "p-2", children: [
13988
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
13836
13989
  themes.map((opt) => {
13837
13990
  const Icon = opt.icon;
13838
13991
  const active = theme === opt.value;
13839
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
13992
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
13840
13993
  Button_default,
13841
13994
  {
13842
13995
  variant: "ghost",
@@ -13852,9 +14005,9 @@ function ThemeToggleHeadless({
13852
14005
  role: "menuitemradio",
13853
14006
  "aria-checked": active,
13854
14007
  children: [
13855
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Icon, { className: "h-4 w-4" }),
13856
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "flex-1 text-left", children: opt.label }),
13857
- active && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
14008
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { className: "h-4 w-4" }),
14009
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "flex-1 text-left", children: opt.label }),
14010
+ active && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
13858
14011
  ]
13859
14012
  },
13860
14013
  opt.value
@@ -13873,7 +14026,7 @@ function ThemeToggleHeadless({
13873
14026
  var import_react34 = require("react");
13874
14027
  var import_react_dom8 = require("react-dom");
13875
14028
  var import_lucide_react32 = require("lucide-react");
13876
- var import_jsx_runtime62 = require("react/jsx-runtime");
14029
+ var import_jsx_runtime63 = require("react/jsx-runtime");
13877
14030
  function LanguageSwitcherHeadless({
13878
14031
  locales,
13879
14032
  currentLocale,
@@ -13895,8 +14048,8 @@ function LanguageSwitcherHeadless({
13895
14048
  const top = rect.bottom + scrollTop + 8;
13896
14049
  return { top, left, width };
13897
14050
  };
13898
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cn("relative", className), children: [
13899
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
14051
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cn("relative", className), children: [
14052
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
13900
14053
  Button_default,
13901
14054
  {
13902
14055
  variant: "ghost",
@@ -13915,22 +14068,22 @@ function LanguageSwitcherHeadless({
13915
14068
  "aria-expanded": isOpen,
13916
14069
  "aria-label": labels?.heading ?? "Language",
13917
14070
  title: labels?.heading ?? "Language",
13918
- children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react32.Globe, { className: "h-5 w-5" })
14071
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react32.Globe, { className: "h-5 w-5" })
13919
14072
  }
13920
14073
  ),
13921
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
13922
- typeof window !== "undefined" && (0, import_react_dom8.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
14074
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
14075
+ typeof window !== "undefined" && (0, import_react_dom8.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
13923
14076
  typeof window !== "undefined" && dropdownPosition && (0, import_react_dom8.createPortal)(
13924
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
14077
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
13925
14078
  "div",
13926
14079
  {
13927
14080
  className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
13928
14081
  style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
13929
14082
  onMouseDown: (e) => e.stopPropagation(),
13930
14083
  role: "menu",
13931
- children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "p-2", children: [
13932
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
13933
- locales.map((language) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
14084
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "p-2", children: [
14085
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
14086
+ locales.map((language) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
13934
14087
  Button_default,
13935
14088
  {
13936
14089
  variant: "ghost",
@@ -13943,9 +14096,9 @@ function LanguageSwitcherHeadless({
13943
14096
  role: "menuitemradio",
13944
14097
  "aria-checked": currentLocale === language.code,
13945
14098
  children: [
13946
- language.flag && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "text-lg", children: language.flag }),
13947
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "flex-1 text-left", children: language.name }),
13948
- currentLocale === language.code && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
14099
+ language.flag && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-lg", children: language.flag }),
14100
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "flex-1 text-left", children: language.name }),
14101
+ currentLocale === language.code && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
13949
14102
  ]
13950
14103
  },
13951
14104
  language.code
@@ -14375,7 +14528,7 @@ var VARIANT_STYLES_ALERT = {
14375
14528
  };
14376
14529
 
14377
14530
  // src/contexts/TranslationContext.tsx
14378
- var React50 = __toESM(require("react"), 1);
14531
+ var React51 = __toESM(require("react"), 1);
14379
14532
 
14380
14533
  // locales/en.json
14381
14534
  var en_default = {
@@ -14678,16 +14831,16 @@ var ja_default = {
14678
14831
  };
14679
14832
 
14680
14833
  // src/contexts/TranslationContext.tsx
14681
- var import_jsx_runtime63 = require("react/jsx-runtime");
14834
+ var import_jsx_runtime64 = require("react/jsx-runtime");
14682
14835
  var defaultTranslations2 = {
14683
14836
  en: en_default,
14684
14837
  vi: vi_default,
14685
14838
  ko: ko_default,
14686
14839
  ja: ja_default
14687
14840
  };
14688
- var TranslationContext2 = React50.createContext(null);
14841
+ var TranslationContext2 = React51.createContext(null);
14689
14842
  var TranslationProvider = ({ children, locale = "en", translations }) => {
14690
- const t = React50.useCallback(
14843
+ const t = React51.useCallback(
14691
14844
  (namespace) => {
14692
14845
  return (key) => {
14693
14846
  const mergedTranslations = {
@@ -14712,10 +14865,10 @@ var TranslationProvider = ({ children, locale = "en", translations }) => {
14712
14865
  },
14713
14866
  [locale, translations]
14714
14867
  );
14715
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TranslationContext2.Provider, { value: { locale, t }, children });
14868
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(TranslationContext2.Provider, { value: { locale, t }, children });
14716
14869
  };
14717
14870
  var useUnderverseTranslations = (namespace) => {
14718
- const context = React50.useContext(TranslationContext2);
14871
+ const context = React51.useContext(TranslationContext2);
14719
14872
  if (!context) {
14720
14873
  return (key) => {
14721
14874
  const parts = namespace.split(".");
@@ -14737,13 +14890,13 @@ var useUnderverseTranslations = (namespace) => {
14737
14890
  return context.t(namespace);
14738
14891
  };
14739
14892
  var useUnderverseLocale = () => {
14740
- const context = React50.useContext(TranslationContext2);
14893
+ const context = React51.useContext(TranslationContext2);
14741
14894
  return context?.locale || "en";
14742
14895
  };
14743
14896
 
14744
14897
  // src/hooks/useSmartTranslations.tsx
14745
- var React51 = __toESM(require("react"), 1);
14746
- var import_jsx_runtime64 = require("react/jsx-runtime");
14898
+ var React52 = __toESM(require("react"), 1);
14899
+ var import_jsx_runtime65 = require("react/jsx-runtime");
14747
14900
  var nextIntlHooks = null;
14748
14901
  try {
14749
14902
  const nextIntl = require("next-intl");
@@ -14754,12 +14907,12 @@ try {
14754
14907
  } catch {
14755
14908
  nextIntlHooks = null;
14756
14909
  }
14757
- var ForceInternalContext = React51.createContext(false);
14910
+ var ForceInternalContext = React52.createContext(false);
14758
14911
  var ForceInternalTranslationsProvider = ({ children }) => {
14759
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ForceInternalContext.Provider, { value: true, children });
14912
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ForceInternalContext.Provider, { value: true, children });
14760
14913
  };
14761
14914
  function useSmartTranslations(namespace) {
14762
- const forceInternal = React51.useContext(ForceInternalContext);
14915
+ const forceInternal = React52.useContext(ForceInternalContext);
14763
14916
  const internalT = useUnderverseTranslations(namespace);
14764
14917
  if (forceInternal || !nextIntlHooks?.useTranslations) {
14765
14918
  return internalT;
@@ -14772,7 +14925,7 @@ function useSmartTranslations(namespace) {
14772
14925
  }
14773
14926
  }
14774
14927
  function useSmartLocale() {
14775
- const forceInternal = React51.useContext(ForceInternalContext);
14928
+ const forceInternal = React52.useContext(ForceInternalContext);
14776
14929
  const internalLocale = useUnderverseLocale();
14777
14930
  if (forceInternal || !nextIntlHooks?.useLocale) {
14778
14931
  return internalLocale;
@@ -14826,6 +14979,17 @@ function getUnderverseMessages(locale = "en") {
14826
14979
  FallingIcons,
14827
14980
  FloatingContacts,
14828
14981
  ForceInternalTranslationsProvider,
14982
+ Form,
14983
+ FormActions,
14984
+ FormCheckbox,
14985
+ FormControl,
14986
+ FormDescription,
14987
+ FormField,
14988
+ FormInput,
14989
+ FormItem,
14990
+ FormLabel,
14991
+ FormMessage,
14992
+ FormSubmitButton,
14829
14993
  GaugeChart,
14830
14994
  GlobalLoading,
14831
14995
  GradientBadge,
@@ -14922,6 +15086,7 @@ function getUnderverseMessages(locale = "en") {
14922
15086
  injectAnimationStyles,
14923
15087
  shadcnAnimationStyles,
14924
15088
  underverseMessages,
15089
+ useFormField,
14925
15090
  useShadCNAnimations,
14926
15091
  useSmartLocale,
14927
15092
  useSmartTranslations,