@underverse-ui/underverse 0.2.65 → 0.2.66

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");
@@ -13598,9 +13610,152 @@ function DataTable({
13598
13610
  }
13599
13611
  var DataTable_default = DataTable;
13600
13612
 
13613
+ // ../../components/ui/Form.tsx
13614
+ var React49 = __toESM(require("react"), 1);
13615
+ var import_react_hook_form = require("react-hook-form");
13616
+ var import_jsx_runtime58 = require("react/jsx-runtime");
13617
+ var FormConfigContext = React49.createContext({ size: "md" });
13618
+ var FormWrapper = ({
13619
+ children,
13620
+ onSubmit,
13621
+ initialValues,
13622
+ validationSchema,
13623
+ className,
13624
+ size = "md",
13625
+ ...props
13626
+ }) => {
13627
+ const methods = (0, import_react_hook_form.useForm)({
13628
+ defaultValues: initialValues
13629
+ });
13630
+ React49.useEffect(() => {
13631
+ if (initialValues) {
13632
+ methods.reset(initialValues);
13633
+ }
13634
+ }, [JSON.stringify(initialValues)]);
13635
+ const { validationSchema: _, ...formProps } = props;
13636
+ 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 }) }) });
13637
+ };
13638
+ var Form = FormWrapper;
13639
+ var FormFieldContext = React49.createContext({});
13640
+ var FormField = ({
13641
+ ...props
13642
+ }) => {
13643
+ 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 }) });
13644
+ };
13645
+ var useFormField = () => {
13646
+ const fieldContext = React49.useContext(FormFieldContext);
13647
+ const itemContext = React49.useContext(FormItemContext);
13648
+ const { getFieldState, formState } = (0, import_react_hook_form.useFormContext)();
13649
+ if (!fieldContext) {
13650
+ try {
13651
+ const t = useTranslations("Form");
13652
+ throw new Error(t("validation.mustBeUsedWithinForm"));
13653
+ } catch {
13654
+ throw new Error("useFormField must be used within FormField");
13655
+ }
13656
+ }
13657
+ const fieldState = getFieldState(fieldContext.name, formState);
13658
+ const { id } = itemContext;
13659
+ return {
13660
+ id,
13661
+ name: fieldContext.name,
13662
+ formItemId: `${id}-form-item`,
13663
+ formDescriptionId: `${id}-form-item-description`,
13664
+ formMessageId: `${id}-form-item-message`,
13665
+ ...fieldState
13666
+ };
13667
+ };
13668
+ var FormItemContext = React49.createContext({});
13669
+ var FormItem = React49.forwardRef(({ className, ...props }, ref) => {
13670
+ const id = React49.useId();
13671
+ 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 }) });
13672
+ });
13673
+ FormItem.displayName = "FormItem";
13674
+ var FormLabel = React49.forwardRef(
13675
+ ({ className, children, required, ...props }, ref) => {
13676
+ const { error, formItemId } = useFormField();
13677
+ const config = React49.useContext(FormConfigContext);
13678
+ const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
13679
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props, children: [
13680
+ children,
13681
+ required && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-destructive ml-1", children: "*" })
13682
+ ] });
13683
+ }
13684
+ );
13685
+ FormLabel.displayName = "FormLabel";
13686
+ var FormControl = React49.forwardRef(({ ...props }, ref) => {
13687
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
13688
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13689
+ "div",
13690
+ {
13691
+ ref,
13692
+ id: formItemId,
13693
+ "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`,
13694
+ "aria-invalid": !!error,
13695
+ ...props
13696
+ }
13697
+ );
13698
+ });
13699
+ FormControl.displayName = "FormControl";
13700
+ var FormDescription = React49.forwardRef(({ className, ...props }, ref) => {
13701
+ const { formDescriptionId } = useFormField();
13702
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
13703
+ });
13704
+ FormDescription.displayName = "FormDescription";
13705
+ var FormMessage = React49.forwardRef(({ className, children, ...props }, ref) => {
13706
+ const { error, formMessageId } = useFormField();
13707
+ const body = error ? String(error?.message) : children;
13708
+ if (!body) {
13709
+ return null;
13710
+ }
13711
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
13712
+ });
13713
+ FormMessage.displayName = "FormMessage";
13714
+ var FormInput = React49.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13715
+ FormField,
13716
+ {
13717
+ name,
13718
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(FormItem, { children: [
13719
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Input_default, { size: props.size ?? size, ...field, ...props }) }),
13720
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormMessage, {})
13721
+ ] })
13722
+ }
13723
+ ) }));
13724
+ FormInput.displayName = "FormInput";
13725
+ var FormCheckbox = React49.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13726
+ FormField,
13727
+ {
13728
+ name,
13729
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(FormItem, { children: [
13730
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
13731
+ Checkbox,
13732
+ {
13733
+ ref,
13734
+ checked: field.value,
13735
+ onChange: (e) => field.onChange(e.target.checked),
13736
+ labelClassName: cn(
13737
+ // align label text size with inputs/buttons by form size
13738
+ size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
13739
+ props.labelClassName
13740
+ ),
13741
+ ...props
13742
+ }
13743
+ ) }),
13744
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(FormMessage, {})
13745
+ ] })
13746
+ }
13747
+ ) }));
13748
+ FormCheckbox.displayName = "FormCheckbox";
13749
+ var FormActions = React49.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
13750
+ FormActions.displayName = "FormActions";
13751
+ var FormSubmitButton = React49.forwardRef(
13752
+ ({ 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 }) })
13753
+ );
13754
+ FormSubmitButton.displayName = "FormSubmitButton";
13755
+
13601
13756
  // ../../components/ui/NotificationModal.tsx
13602
13757
  var import_lucide_react28 = require("lucide-react");
13603
- var import_jsx_runtime58 = require("react/jsx-runtime");
13758
+ var import_jsx_runtime59 = require("react/jsx-runtime");
13604
13759
  function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
13605
13760
  const t = useTranslations("Common");
13606
13761
  if (!notification) return null;
@@ -13621,20 +13776,20 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
13621
13776
  onClose();
13622
13777
  }
13623
13778
  };
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") })
13779
+ 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: [
13780
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
13781
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn("w-2 h-2 rounded-full", !notification.is_read ? "bg-primary" : "bg-border") }),
13782
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
13628
13783
  ] }),
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" }),
13784
+ notification.title && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
13785
+ notification.body && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
13786
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
13787
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex gap-2 justify-end pt-2", children: [
13788
+ hasLink && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(Button_default, { variant: "primary", size: "sm", onClick: handleLinkClick, className: "gap-2", children: [
13789
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react28.ExternalLink, { className: "w-4 h-4" }),
13635
13790
  openLinkText || t("openLink")
13636
13791
  ] }),
13637
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
13792
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
13638
13793
  ] })
13639
13794
  ] }) });
13640
13795
  }
@@ -13644,9 +13799,9 @@ var NotificationModal_default = NotificationModal;
13644
13799
  var import_link2 = __toESM(require("next/link"), 1);
13645
13800
  var import_navigation = require("next/navigation");
13646
13801
  var import_lucide_react29 = require("lucide-react");
13647
- var import_jsx_runtime59 = require("react/jsx-runtime");
13802
+ var import_jsx_runtime60 = require("react/jsx-runtime");
13648
13803
  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)(
13804
+ 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
13805
  "path",
13651
13806
  {
13652
13807
  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 +13810,7 @@ function MessengerIcon(props) {
13655
13810
  ) });
13656
13811
  }
13657
13812
  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)(
13813
+ 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
13814
  "path",
13660
13815
  {
13661
13816
  fill: "white",
@@ -13664,7 +13819,7 @@ function ZaloIcon(props) {
13664
13819
  ) });
13665
13820
  }
13666
13821
  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" }) });
13822
+ 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
13823
  }
13669
13824
  function FloatingContacts({ className }) {
13670
13825
  const pathname = (0, import_navigation.usePathname)();
@@ -13699,8 +13854,8 @@ function FloatingContacts({ className }) {
13699
13854
  external: true
13700
13855
  }
13701
13856
  ];
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)(
13857
+ 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: [
13858
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
13704
13859
  import_link2.default,
13705
13860
  {
13706
13861
  href: `tel:${hotline.replace(/\D/g, "")}`,
@@ -13711,10 +13866,10 @@ function FloatingContacts({ className }) {
13711
13866
  "hover:scale-105 active:scale-95 transition-transform",
13712
13867
  "bg-[#22c55e]"
13713
13868
  ),
13714
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react29.Phone, { className: "w-6 h-6" })
13869
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react29.Phone, { className: "w-6 h-6" })
13715
13870
  }
13716
13871
  ),
13717
- moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
13872
+ moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
13718
13873
  import_link2.default,
13719
13874
  {
13720
13875
  href,
@@ -13726,7 +13881,7 @@ function FloatingContacts({ className }) {
13726
13881
  "hover:scale-105 active:scale-95 transition-transform",
13727
13882
  bg
13728
13883
  ),
13729
- children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Icon, { className: "w-6 h-6" })
13884
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { className: "w-6 h-6" })
13730
13885
  },
13731
13886
  key
13732
13887
  ))
@@ -13735,7 +13890,7 @@ function FloatingContacts({ className }) {
13735
13890
 
13736
13891
  // ../../components/ui/AccessDenied.tsx
13737
13892
  var import_lucide_react30 = require("lucide-react");
13738
- var import_jsx_runtime60 = require("react/jsx-runtime");
13893
+ var import_jsx_runtime61 = require("react/jsx-runtime");
13739
13894
  var VARIANT_STYLES = {
13740
13895
  destructive: { bg: "bg-destructive/5", border: "border-destructive/20", text: "text-destructive" },
13741
13896
  warning: { bg: "bg-warning/5", border: "border-warning/20", text: "text-warning" },
@@ -13756,13 +13911,13 @@ function AccessDenied({
13756
13911
  }) {
13757
13912
  const styles = VARIANT_STYLES[variant];
13758
13913
  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 })
13914
+ 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: [
13915
+ /* @__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) }) }),
13916
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
13917
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
13918
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
13764
13919
  ] }),
13765
- children && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
13920
+ children && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
13766
13921
  ] }) });
13767
13922
  }
13768
13923
 
@@ -13770,7 +13925,7 @@ function AccessDenied({
13770
13925
  var import_lucide_react31 = require("lucide-react");
13771
13926
  var import_react33 = require("react");
13772
13927
  var import_react_dom7 = require("react-dom");
13773
- var import_jsx_runtime61 = require("react/jsx-runtime");
13928
+ var import_jsx_runtime62 = require("react/jsx-runtime");
13774
13929
  function ThemeToggleHeadless({
13775
13930
  theme,
13776
13931
  onChange,
@@ -13799,8 +13954,8 @@ function ThemeToggleHeadless({
13799
13954
  const top = rect.bottom + scrollTop + 8;
13800
13955
  return { top, left, width };
13801
13956
  };
13802
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: cn("relative", className), children: [
13803
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
13957
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cn("relative", className), children: [
13958
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
13804
13959
  Button_default,
13805
13960
  {
13806
13961
  variant: "ghost",
@@ -13818,25 +13973,25 @@ function ThemeToggleHeadless({
13818
13973
  "aria-haspopup": "menu",
13819
13974
  "aria-expanded": isOpen,
13820
13975
  "aria-label": labels?.heading ?? "Theme",
13821
- children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CurrentIcon, { className: "h-5 w-5" })
13976
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(CurrentIcon, { className: "h-5 w-5" })
13822
13977
  }
13823
13978
  ),
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),
13979
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
13980
+ 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
13981
  typeof window !== "undefined" && dropdownPosition && (0, import_react_dom7.createPortal)(
13827
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
13982
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
13828
13983
  "div",
13829
13984
  {
13830
13985
  className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
13831
13986
  style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
13832
13987
  onMouseDown: (e) => e.stopPropagation(),
13833
13988
  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" }),
13989
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "p-2", children: [
13990
+ /* @__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
13991
  themes.map((opt) => {
13837
13992
  const Icon = opt.icon;
13838
13993
  const active = theme === opt.value;
13839
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
13994
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
13840
13995
  Button_default,
13841
13996
  {
13842
13997
  variant: "ghost",
@@ -13852,9 +14007,9 @@ function ThemeToggleHeadless({
13852
14007
  role: "menuitemradio",
13853
14008
  "aria-checked": active,
13854
14009
  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" })
14010
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { className: "h-4 w-4" }),
14011
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "flex-1 text-left", children: opt.label }),
14012
+ active && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
13858
14013
  ]
13859
14014
  },
13860
14015
  opt.value
@@ -13873,7 +14028,7 @@ function ThemeToggleHeadless({
13873
14028
  var import_react34 = require("react");
13874
14029
  var import_react_dom8 = require("react-dom");
13875
14030
  var import_lucide_react32 = require("lucide-react");
13876
- var import_jsx_runtime62 = require("react/jsx-runtime");
14031
+ var import_jsx_runtime63 = require("react/jsx-runtime");
13877
14032
  function LanguageSwitcherHeadless({
13878
14033
  locales,
13879
14034
  currentLocale,
@@ -13895,8 +14050,8 @@ function LanguageSwitcherHeadless({
13895
14050
  const top = rect.bottom + scrollTop + 8;
13896
14051
  return { top, left, width };
13897
14052
  };
13898
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cn("relative", className), children: [
13899
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
14053
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cn("relative", className), children: [
14054
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
13900
14055
  Button_default,
13901
14056
  {
13902
14057
  variant: "ghost",
@@ -13915,22 +14070,22 @@ function LanguageSwitcherHeadless({
13915
14070
  "aria-expanded": isOpen,
13916
14071
  "aria-label": labels?.heading ?? "Language",
13917
14072
  title: labels?.heading ?? "Language",
13918
- children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react32.Globe, { className: "h-5 w-5" })
14073
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react32.Globe, { className: "h-5 w-5" })
13919
14074
  }
13920
14075
  ),
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),
14076
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
14077
+ 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
14078
  typeof window !== "undefined" && dropdownPosition && (0, import_react_dom8.createPortal)(
13924
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
14079
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
13925
14080
  "div",
13926
14081
  {
13927
14082
  className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
13928
14083
  style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
13929
14084
  onMouseDown: (e) => e.stopPropagation(),
13930
14085
  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)(
14086
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "p-2", children: [
14087
+ /* @__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" }),
14088
+ locales.map((language) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
13934
14089
  Button_default,
13935
14090
  {
13936
14091
  variant: "ghost",
@@ -13943,9 +14098,9 @@ function LanguageSwitcherHeadless({
13943
14098
  role: "menuitemradio",
13944
14099
  "aria-checked": currentLocale === language.code,
13945
14100
  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" })
14101
+ language.flag && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-lg", children: language.flag }),
14102
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "flex-1 text-left", children: language.name }),
14103
+ currentLocale === language.code && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
13949
14104
  ]
13950
14105
  },
13951
14106
  language.code
@@ -14375,7 +14530,7 @@ var VARIANT_STYLES_ALERT = {
14375
14530
  };
14376
14531
 
14377
14532
  // src/contexts/TranslationContext.tsx
14378
- var React50 = __toESM(require("react"), 1);
14533
+ var React51 = __toESM(require("react"), 1);
14379
14534
 
14380
14535
  // locales/en.json
14381
14536
  var en_default = {
@@ -14678,16 +14833,16 @@ var ja_default = {
14678
14833
  };
14679
14834
 
14680
14835
  // src/contexts/TranslationContext.tsx
14681
- var import_jsx_runtime63 = require("react/jsx-runtime");
14836
+ var import_jsx_runtime64 = require("react/jsx-runtime");
14682
14837
  var defaultTranslations2 = {
14683
14838
  en: en_default,
14684
14839
  vi: vi_default,
14685
14840
  ko: ko_default,
14686
14841
  ja: ja_default
14687
14842
  };
14688
- var TranslationContext2 = React50.createContext(null);
14843
+ var TranslationContext2 = React51.createContext(null);
14689
14844
  var TranslationProvider = ({ children, locale = "en", translations }) => {
14690
- const t = React50.useCallback(
14845
+ const t = React51.useCallback(
14691
14846
  (namespace) => {
14692
14847
  return (key) => {
14693
14848
  const mergedTranslations = {
@@ -14712,10 +14867,10 @@ var TranslationProvider = ({ children, locale = "en", translations }) => {
14712
14867
  },
14713
14868
  [locale, translations]
14714
14869
  );
14715
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TranslationContext2.Provider, { value: { locale, t }, children });
14870
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(TranslationContext2.Provider, { value: { locale, t }, children });
14716
14871
  };
14717
14872
  var useUnderverseTranslations = (namespace) => {
14718
- const context = React50.useContext(TranslationContext2);
14873
+ const context = React51.useContext(TranslationContext2);
14719
14874
  if (!context) {
14720
14875
  return (key) => {
14721
14876
  const parts = namespace.split(".");
@@ -14737,13 +14892,13 @@ var useUnderverseTranslations = (namespace) => {
14737
14892
  return context.t(namespace);
14738
14893
  };
14739
14894
  var useUnderverseLocale = () => {
14740
- const context = React50.useContext(TranslationContext2);
14895
+ const context = React51.useContext(TranslationContext2);
14741
14896
  return context?.locale || "en";
14742
14897
  };
14743
14898
 
14744
14899
  // src/hooks/useSmartTranslations.tsx
14745
- var React51 = __toESM(require("react"), 1);
14746
- var import_jsx_runtime64 = require("react/jsx-runtime");
14900
+ var React52 = __toESM(require("react"), 1);
14901
+ var import_jsx_runtime65 = require("react/jsx-runtime");
14747
14902
  var nextIntlHooks = null;
14748
14903
  try {
14749
14904
  const nextIntl = require("next-intl");
@@ -14754,12 +14909,12 @@ try {
14754
14909
  } catch {
14755
14910
  nextIntlHooks = null;
14756
14911
  }
14757
- var ForceInternalContext = React51.createContext(false);
14912
+ var ForceInternalContext = React52.createContext(false);
14758
14913
  var ForceInternalTranslationsProvider = ({ children }) => {
14759
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ForceInternalContext.Provider, { value: true, children });
14914
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ForceInternalContext.Provider, { value: true, children });
14760
14915
  };
14761
14916
  function useSmartTranslations(namespace) {
14762
- const forceInternal = React51.useContext(ForceInternalContext);
14917
+ const forceInternal = React52.useContext(ForceInternalContext);
14763
14918
  const internalT = useUnderverseTranslations(namespace);
14764
14919
  if (forceInternal || !nextIntlHooks?.useTranslations) {
14765
14920
  return internalT;
@@ -14772,7 +14927,7 @@ function useSmartTranslations(namespace) {
14772
14927
  }
14773
14928
  }
14774
14929
  function useSmartLocale() {
14775
- const forceInternal = React51.useContext(ForceInternalContext);
14930
+ const forceInternal = React52.useContext(ForceInternalContext);
14776
14931
  const internalLocale = useUnderverseLocale();
14777
14932
  if (forceInternal || !nextIntlHooks?.useLocale) {
14778
14933
  return internalLocale;
@@ -14826,6 +14981,17 @@ function getUnderverseMessages(locale = "en") {
14826
14981
  FallingIcons,
14827
14982
  FloatingContacts,
14828
14983
  ForceInternalTranslationsProvider,
14984
+ Form,
14985
+ FormActions,
14986
+ FormCheckbox,
14987
+ FormControl,
14988
+ FormDescription,
14989
+ FormField,
14990
+ FormInput,
14991
+ FormItem,
14992
+ FormLabel,
14993
+ FormMessage,
14994
+ FormSubmitButton,
14829
14995
  GaugeChart,
14830
14996
  GlobalLoading,
14831
14997
  GradientBadge,
@@ -14922,6 +15088,7 @@ function getUnderverseMessages(locale = "en") {
14922
15088
  injectAnimationStyles,
14923
15089
  shadcnAnimationStyles,
14924
15090
  underverseMessages,
15091
+ useFormField,
14925
15092
  useShadCNAnimations,
14926
15093
  useSmartLocale,
14927
15094
  useSmartTranslations,