warqadui 0.0.4 → 0.0.6

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.
Files changed (179) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/apps/dev-app/.env +1 -0
  3. package/apps/dev-app/errors.log +0 -0
  4. package/apps/dev-app/index.html +12 -0
  5. package/apps/dev-app/node_modules/.vite/deps/@tanstack_react-table.js +3254 -0
  6. package/apps/dev-app/node_modules/.vite/deps/@tanstack_react-table.js.map +7 -0
  7. package/apps/dev-app/node_modules/.vite/deps/_metadata.json +178 -0
  8. package/apps/dev-app/node_modules/.vite/deps/antd.js +108982 -0
  9. package/apps/dev-app/node_modules/.vite/deps/antd.js.map +7 -0
  10. package/apps/dev-app/node_modules/.vite/deps/axios.js +2751 -0
  11. package/apps/dev-app/node_modules/.vite/deps/axios.js.map +7 -0
  12. package/apps/dev-app/node_modules/.vite/deps/chunk-5OG7DCD7.js +41 -0
  13. package/apps/dev-app/node_modules/.vite/deps/chunk-5OG7DCD7.js.map +7 -0
  14. package/apps/dev-app/node_modules/.vite/deps/chunk-7YRZYZRE.js +7807 -0
  15. package/apps/dev-app/node_modules/.vite/deps/chunk-7YRZYZRE.js.map +7 -0
  16. package/apps/dev-app/node_modules/.vite/deps/chunk-DC5AMYBS.js +39 -0
  17. package/apps/dev-app/node_modules/.vite/deps/chunk-DC5AMYBS.js.map +7 -0
  18. package/apps/dev-app/node_modules/.vite/deps/chunk-DKXRQMOD.js +135 -0
  19. package/apps/dev-app/node_modules/.vite/deps/chunk-DKXRQMOD.js.map +7 -0
  20. package/apps/dev-app/node_modules/.vite/deps/chunk-EL47BWQR.js +37 -0
  21. package/apps/dev-app/node_modules/.vite/deps/chunk-EL47BWQR.js.map +7 -0
  22. package/apps/dev-app/node_modules/.vite/deps/chunk-HHL3MHGV.js +288 -0
  23. package/apps/dev-app/node_modules/.vite/deps/chunk-HHL3MHGV.js.map +7 -0
  24. package/apps/dev-app/node_modules/.vite/deps/chunk-IGGUWUPT.js +60 -0
  25. package/apps/dev-app/node_modules/.vite/deps/chunk-IGGUWUPT.js.map +7 -0
  26. package/apps/dev-app/node_modules/.vite/deps/chunk-IGXZPJXT.js +928 -0
  27. package/apps/dev-app/node_modules/.vite/deps/chunk-IGXZPJXT.js.map +7 -0
  28. package/apps/dev-app/node_modules/.vite/deps/chunk-L2GCM37S.js +21628 -0
  29. package/apps/dev-app/node_modules/.vite/deps/chunk-L2GCM37S.js.map +7 -0
  30. package/apps/dev-app/node_modules/.vite/deps/chunk-LDRT62EN.js +14806 -0
  31. package/apps/dev-app/node_modules/.vite/deps/chunk-LDRT62EN.js.map +7 -0
  32. package/apps/dev-app/node_modules/.vite/deps/chunk-M7DZDBHW.js +14 -0
  33. package/apps/dev-app/node_modules/.vite/deps/chunk-M7DZDBHW.js.map +7 -0
  34. package/apps/dev-app/node_modules/.vite/deps/chunk-S54SBVCU.js +1906 -0
  35. package/apps/dev-app/node_modules/.vite/deps/chunk-S54SBVCU.js.map +7 -0
  36. package/apps/dev-app/node_modules/.vite/deps/chunk-WFNHCR67.js +21 -0
  37. package/apps/dev-app/node_modules/.vite/deps/chunk-WFNHCR67.js.map +7 -0
  38. package/apps/dev-app/node_modules/.vite/deps/clsx.js +10 -0
  39. package/apps/dev-app/node_modules/.vite/deps/clsx.js.map +7 -0
  40. package/apps/dev-app/node_modules/.vite/deps/dayjs.js +6 -0
  41. package/apps/dev-app/node_modules/.vite/deps/dayjs.js.map +7 -0
  42. package/apps/dev-app/node_modules/.vite/deps/dayjs_plugin_customParseFormat.js +6 -0
  43. package/apps/dev-app/node_modules/.vite/deps/dayjs_plugin_customParseFormat.js.map +7 -0
  44. package/apps/dev-app/node_modules/.vite/deps/framer-motion.js +12388 -0
  45. package/apps/dev-app/node_modules/.vite/deps/framer-motion.js.map +7 -0
  46. package/apps/dev-app/node_modules/.vite/deps/html2canvas-pro.js +9713 -0
  47. package/apps/dev-app/node_modules/.vite/deps/html2canvas-pro.js.map +7 -0
  48. package/apps/dev-app/node_modules/.vite/deps/html2canvas.esm-VL7GM4AH.js +8 -0
  49. package/apps/dev-app/node_modules/.vite/deps/html2canvas.esm-VL7GM4AH.js.map +7 -0
  50. package/apps/dev-app/node_modules/.vite/deps/index.es-3WTXOFZ2.js +10392 -0
  51. package/apps/dev-app/node_modules/.vite/deps/index.es-3WTXOFZ2.js.map +7 -0
  52. package/apps/dev-app/node_modules/.vite/deps/jspdf.js +41 -0
  53. package/apps/dev-app/node_modules/.vite/deps/jspdf.js.map +7 -0
  54. package/apps/dev-app/node_modules/.vite/deps/lucide-react.js +31586 -0
  55. package/apps/dev-app/node_modules/.vite/deps/lucide-react.js.map +7 -0
  56. package/apps/dev-app/node_modules/.vite/deps/package.json +3 -0
  57. package/apps/dev-app/node_modules/.vite/deps/purify.es-JNLDEIMX.js +1029 -0
  58. package/apps/dev-app/node_modules/.vite/deps/purify.es-JNLDEIMX.js.map +7 -0
  59. package/apps/dev-app/node_modules/.vite/deps/react-dom.js +7 -0
  60. package/apps/dev-app/node_modules/.vite/deps/react-dom.js.map +7 -0
  61. package/apps/dev-app/node_modules/.vite/deps/react-dom_client.js +8 -0
  62. package/apps/dev-app/node_modules/.vite/deps/react-dom_client.js.map +7 -0
  63. package/apps/dev-app/node_modules/.vite/deps/react-hook-form.js +2233 -0
  64. package/apps/dev-app/node_modules/.vite/deps/react-hook-form.js.map +7 -0
  65. package/apps/dev-app/node_modules/.vite/deps/react-phone-number-input.js +9307 -0
  66. package/apps/dev-app/node_modules/.vite/deps/react-phone-number-input.js.map +7 -0
  67. package/apps/dev-app/node_modules/.vite/deps/react-router-dom.js +14234 -0
  68. package/apps/dev-app/node_modules/.vite/deps/react-router-dom.js.map +7 -0
  69. package/apps/dev-app/node_modules/.vite/deps/react-to-pdf.js +268 -0
  70. package/apps/dev-app/node_modules/.vite/deps/react-to-pdf.js.map +7 -0
  71. package/apps/dev-app/node_modules/.vite/deps/react.js +6 -0
  72. package/apps/dev-app/node_modules/.vite/deps/react.js.map +7 -0
  73. package/apps/dev-app/node_modules/.vite/deps/react_jsx-dev-runtime.js +913 -0
  74. package/apps/dev-app/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +7 -0
  75. package/apps/dev-app/node_modules/.vite/deps/react_jsx-runtime.js +7 -0
  76. package/apps/dev-app/node_modules/.vite/deps/react_jsx-runtime.js.map +7 -0
  77. package/apps/dev-app/node_modules/.vite/deps/tailwind-merge.js +2534 -0
  78. package/apps/dev-app/node_modules/.vite/deps/tailwind-merge.js.map +7 -0
  79. package/apps/dev-app/node_modules/tailwindcss/LICENSE +21 -0
  80. package/apps/dev-app/node_modules/tailwindcss/README.md +36 -0
  81. package/apps/dev-app/node_modules/tailwindcss/dist/chunk-L5IEUH3R.mjs +38 -0
  82. package/apps/dev-app/node_modules/tailwindcss/dist/chunk-UWKE2Z6N.mjs +1 -0
  83. package/apps/dev-app/node_modules/tailwindcss/dist/chunk-X4GG3EDV.mjs +1 -0
  84. package/apps/dev-app/node_modules/tailwindcss/dist/colors-C__qRT83.d.ts +347 -0
  85. package/apps/dev-app/node_modules/tailwindcss/dist/colors.d.mts +347 -0
  86. package/apps/dev-app/node_modules/tailwindcss/dist/colors.d.ts +5 -0
  87. package/apps/dev-app/node_modules/tailwindcss/dist/colors.js +1 -0
  88. package/apps/dev-app/node_modules/tailwindcss/dist/colors.mjs +1 -0
  89. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.d.mts +1199 -0
  90. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.d.ts +1199 -0
  91. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.js +1 -0
  92. package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.mjs +1 -0
  93. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.d.mts +6 -0
  94. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.d.ts +6 -0
  95. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.js +3 -0
  96. package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.mjs +1 -0
  97. package/apps/dev-app/node_modules/tailwindcss/dist/lib.d.mts +378 -0
  98. package/apps/dev-app/node_modules/tailwindcss/dist/lib.d.ts +3 -0
  99. package/apps/dev-app/node_modules/tailwindcss/dist/lib.js +38 -0
  100. package/apps/dev-app/node_modules/tailwindcss/dist/lib.mjs +1 -0
  101. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.d.mts +11 -0
  102. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.d.ts +134 -0
  103. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.js +1 -0
  104. package/apps/dev-app/node_modules/tailwindcss/dist/plugin.mjs +1 -0
  105. package/apps/dev-app/node_modules/tailwindcss/dist/resolve-config-B4yBzhca.d.ts +29 -0
  106. package/apps/dev-app/node_modules/tailwindcss/dist/resolve-config-QUZ9b-Gn.d.mts +190 -0
  107. package/apps/dev-app/node_modules/tailwindcss/dist/types-CJYAW1ql.d.mts +128 -0
  108. package/apps/dev-app/node_modules/tailwindcss/index.css +944 -0
  109. package/apps/dev-app/node_modules/tailwindcss/package.json +89 -0
  110. package/apps/dev-app/node_modules/tailwindcss/preflight.css +393 -0
  111. package/apps/dev-app/node_modules/tailwindcss/theme.css +510 -0
  112. package/apps/dev-app/node_modules/tailwindcss/utilities.css +1 -0
  113. package/apps/dev-app/package.json +35 -0
  114. package/apps/dev-app/src/App.tsx +74 -0
  115. package/apps/dev-app/src/index.css +18 -0
  116. package/apps/dev-app/src/main.tsx +18 -0
  117. package/apps/dev-app/src/pages/Buttons.tsx +122 -0
  118. package/apps/dev-app/src/pages/DataTable.tsx +208 -0
  119. package/apps/dev-app/src/pages/Fields.tsx +342 -0
  120. package/apps/dev-app/src/pages/Modals.tsx +151 -0
  121. package/apps/dev-app/src/pages/Spins.tsx +161 -0
  122. package/apps/dev-app/ts_errors.txt +0 -0
  123. package/apps/dev-app/tsconfig.json +25 -0
  124. package/apps/dev-app/tsconfig.node.json +10 -0
  125. package/apps/dev-app/vite.config.ts +11 -0
  126. package/package.json +10 -49
  127. package/packages/ui/dist/index.d.mts +356 -0
  128. package/packages/ui/dist/index.d.ts +356 -0
  129. package/packages/ui/dist/index.js +2296 -0
  130. package/packages/ui/dist/index.mjs +2249 -0
  131. package/packages/ui/dist/styles.js +26 -0
  132. package/packages/ui/dist/styles.mjs +24 -0
  133. package/packages/ui/log.txt +0 -0
  134. package/packages/ui/package.json +68 -0
  135. package/packages/ui/postcss.config.js +6 -0
  136. package/packages/ui/src/components/Button.tsx +85 -0
  137. package/packages/ui/src/components/Card.tsx +97 -0
  138. package/packages/ui/src/components/CodeBlock.tsx +53 -0
  139. package/packages/ui/src/components/DashboardLayout.tsx +442 -0
  140. package/packages/ui/src/components/Fields/Input.tsx +191 -0
  141. package/packages/ui/src/components/Fields/PhoneInput.tsx +134 -0
  142. package/packages/ui/src/components/Fields/date.tsx +165 -0
  143. package/packages/ui/src/components/Fields/index.tsx +17 -0
  144. package/packages/ui/src/components/Fields/searchApi.tsx +479 -0
  145. package/packages/ui/src/components/Fields/select.tsx +131 -0
  146. package/packages/ui/src/components/Fields/textArea.tsx +121 -0
  147. package/packages/ui/src/components/LoadingBox.tsx +11 -0
  148. package/packages/ui/src/components/PageHeader.tsx +34 -0
  149. package/packages/ui/src/components/ThemeToggle.tsx +35 -0
  150. package/packages/ui/src/components/modal/Modal.tsx +81 -0
  151. package/packages/ui/src/components/spins/ClassicSpin.tsx +18 -0
  152. package/packages/ui/src/components/spins/LoadingSpin.tsx +45 -0
  153. package/packages/ui/src/components/spins/OverlaySpin.tsx +10 -0
  154. package/packages/ui/src/components/spins/index.tsx +13 -0
  155. package/packages/ui/src/components/tables/DataTable.tsx +261 -0
  156. package/packages/ui/src/components/tables/index.ts +1 -0
  157. package/packages/ui/src/hooks/Fetches/useApis.tsx +197 -0
  158. package/packages/ui/src/hooks/ThemeContext.tsx +56 -0
  159. package/packages/ui/src/hooks/useModal.tsx +38 -0
  160. package/packages/ui/src/hooks/useTheme.ts +34 -0
  161. package/packages/ui/src/index.ts +24 -0
  162. package/packages/ui/src/providers/WarqadProvider.tsx +69 -0
  163. package/packages/ui/src/styles.css +26 -0
  164. package/packages/ui/src/utils/cn.ts +6 -0
  165. package/packages/ui/src/utils/pdf.ts +171 -0
  166. package/packages/ui/tailwind.config.js +13 -0
  167. package/packages/ui/tsconfig.json +17 -0
  168. package/packages/ui/warqad-ui-0.0.1.tgz +0 -0
  169. package/packages/ui/warqadui-0.0.3.tgz +0 -0
  170. package/warqad-ui-0.0.1.tgz +0 -0
  171. package/dist/index.d.mts +0 -35
  172. package/dist/index.d.ts +0 -35
  173. package/dist/index.js +0 -470
  174. package/dist/index.mjs +0 -440
  175. package/dist/styles.js +0 -26
  176. package/dist/styles.mjs +0 -24
  177. /package/{dist → packages/ui/dist}/index.css +0 -0
  178. /package/{dist → packages/ui/dist}/styles.d.mts +0 -0
  179. /package/{dist → packages/ui/dist}/styles.d.ts +0 -0
@@ -0,0 +1,2296 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Button: () => Button,
34
+ Card: () => Card,
35
+ CardContent: () => CardContent,
36
+ CardDescription: () => CardDescription,
37
+ CardFooter: () => CardFooter,
38
+ CardHeader: () => CardHeader,
39
+ CardTitle: () => CardTitle,
40
+ ClassicSpin: () => ClassicSpin,
41
+ CodeBlock: () => CodeBlock,
42
+ DashboardLayout: () => DashboardLayout,
43
+ DataTable: () => DataTable,
44
+ DateInput: () => DateInput,
45
+ Fields: () => Fields_default,
46
+ Input: () => Input,
47
+ LoadingBox: () => LoadingBox,
48
+ LoadingSpin: () => LoadingSpin,
49
+ Modal: () => Modal,
50
+ OverlaySpin: () => OverlaySpin,
51
+ PageHeader: () => PageHeader,
52
+ PhoneInput: () => PhoneInput,
53
+ SearchApi: () => SearchApi,
54
+ Select: () => Select,
55
+ Textarea: () => Textarea,
56
+ ThemeProvider: () => ThemeProvider,
57
+ ThemeToggle: () => ThemeToggle,
58
+ WarqadProvider: () => WarqadProvider,
59
+ generatePdf: () => generatePdf,
60
+ useApi: () => useApis_default,
61
+ useModal: () => useModal,
62
+ useTheme: () => useTheme,
63
+ useWarqadConfig: () => useWarqadConfig
64
+ });
65
+ module.exports = __toCommonJS(index_exports);
66
+
67
+ // src/utils/cn.ts
68
+ var import_clsx = require("clsx");
69
+ var import_tailwind_merge = require("tailwind-merge");
70
+ function cn(...inputs) {
71
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
72
+ }
73
+
74
+ // src/components/Button.tsx
75
+ var import_jsx_runtime = require("react/jsx-runtime");
76
+ var Button = ({
77
+ children,
78
+ className,
79
+ variant = "primary",
80
+ size = "md",
81
+ isLoading,
82
+ icon,
83
+ ...props
84
+ }) => {
85
+ const variants = {
86
+ primary: "bg-[#007AFF] text-white hover:bg-[#0071e3] active:scale-[0.98] active:opacity-90 shadow-[0_1px_2px_rgba(0,0,0,0.1)] focus:ring-[#007AFF]",
87
+ secondary: "bg-[#F5F5F7] text-[#1D1D1F] hover:bg-[#E8E8ED] dark:bg-[#FFFFFF]/10 dark:text-[#F5F5F7] dark:hover:bg-[#FFFFFF]/15 active:scale-[0.98] focus:ring-gray-400",
88
+ outline: "border border-gray-200 dark:border-gray-800 bg-white/50 dark:bg-black/50 backdrop-blur-md text-[#1D1D1F] dark:text-white hover:bg-gray-50 dark:hover:bg-gray-900 active:scale-[0.98] focus:ring-gray-400",
89
+ ghost: "bg-transparent text-[#007AFF] hover:bg-[#007AFF]/10 active:scale-[0.98] focus:ring-[#007AFF]",
90
+ danger: "bg-[#FF3B30] text-white hover:bg-[#E03126] active:scale-[0.98] active:opacity-90 shadow-[0_1px_2px_rgba(0,0,0,0.1)] focus:ring-[#FF3B30]",
91
+ warning: "bg-[#FF9500] text-white hover:bg-[#E68600] active:scale-[0.98] active:opacity-90 shadow-[0_1px_2px_rgba(0,0,0,0.1)] focus:ring-[#FF9500]"
92
+ };
93
+ const sizes = {
94
+ sm: "px-3 py-1.5 text-sm rounded-[10px] gap-1.5 font-medium",
95
+ md: "px-5 py-2.5 rounded-[12px] gap-2 font-medium tracking-tight",
96
+ lg: "px-7 py-3.5 text-lg rounded-[16px] font-semibold tracking-tight gap-2.5"
97
+ };
98
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
99
+ "button",
100
+ {
101
+ className: cn(
102
+ "inline-flex items-center justify-center transition-all duration-200 ease-out focus:outline-none focus:ring-2 focus:ring-offset-1 disabled:opacity-50 select-none cursor-pointer disabled:cursor-not-allowed",
103
+ variants[variant],
104
+ sizes[size],
105
+ className
106
+ ),
107
+ disabled: isLoading || props.disabled,
108
+ ...props,
109
+ children: [
110
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
111
+ "svg",
112
+ {
113
+ className: "animate-spin -ml-1 mr-2 h-4 w-4",
114
+ fill: "none",
115
+ viewBox: "0 0 24 24",
116
+ xmlns: "http://www.w3.org/2000/svg",
117
+ children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
119
+ "circle",
120
+ {
121
+ className: "opacity-25",
122
+ cx: "12",
123
+ cy: "12",
124
+ r: "10",
125
+ stroke: "currentColor",
126
+ strokeWidth: "4"
127
+ }
128
+ ),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
130
+ "path",
131
+ {
132
+ className: "opacity-75",
133
+ fill: "currentColor",
134
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
135
+ }
136
+ )
137
+ ]
138
+ }
139
+ ) : icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex-shrink-0", children: icon }),
140
+ children
141
+ ]
142
+ }
143
+ );
144
+ };
145
+
146
+ // src/components/DashboardLayout.tsx
147
+ var import_react = require("react");
148
+ var import_react_router_dom = require("react-router-dom");
149
+ var import_lucide_react = require("lucide-react");
150
+ var import_framer_motion = require("framer-motion");
151
+ var import_jsx_runtime2 = require("react/jsx-runtime");
152
+ var useMediaQuery = (query) => {
153
+ const [matches, setMatches] = (0, import_react.useState)(() => {
154
+ if (typeof window !== "undefined") {
155
+ return window.matchMedia(query).matches;
156
+ }
157
+ return false;
158
+ });
159
+ (0, import_react.useEffect)(() => {
160
+ const media = window.matchMedia(query);
161
+ if (media.matches !== matches) {
162
+ setMatches(media.matches);
163
+ }
164
+ const listener = () => setMatches(media.matches);
165
+ media.addEventListener("change", listener);
166
+ return () => media.removeEventListener("change", listener);
167
+ }, [matches, query]);
168
+ return matches;
169
+ };
170
+ var isPathActive = (navPath, currentPath) => {
171
+ if (!navPath || !currentPath) return false;
172
+ return currentPath === navPath || navPath !== "/" && currentPath.startsWith(`${navPath}/`);
173
+ };
174
+ var SidebarItem = ({
175
+ item,
176
+ isActive,
177
+ isChildActive,
178
+ onClick,
179
+ isExpanded,
180
+ onToggleExpand,
181
+ isSidebarCollapsed
182
+ }) => {
183
+ const hasSubItems = item.subItems && item.subItems.length > 0;
184
+ const shouldHighlight = isActive || hasSubItems && isExpanded || isChildActive;
185
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-1 group relative ", children: [
186
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
187
+ "button",
188
+ {
189
+ type: "button",
190
+ onClick: item.disabled ? void 0 : hasSubItems ? onToggleExpand : onClick,
191
+ disabled: item.disabled,
192
+ title: isSidebarCollapsed ? item.label : void 0,
193
+ className: cn(
194
+ "w-full flex items-center py-2.5 rounded-xl text-sm font-medium transition-all duration-200",
195
+ isSidebarCollapsed ? "justify-center px-2" : "justify-between px-3",
196
+ shouldHighlight && !item.disabled ? "bg-blue-50 text-blue-700 dark:bg-blue-900/20 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200",
197
+ item.disabled && "opacity-50 cursor-not-allowed grayscale-[0.5]"
198
+ ),
199
+ children: [
200
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
201
+ "div",
202
+ {
203
+ className: cn(
204
+ "flex items-center gap-3 overflow-hidden",
205
+ isSidebarCollapsed ? "justify-center w-full" : ""
206
+ ),
207
+ children: [
208
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
209
+ "span",
210
+ {
211
+ className: cn(
212
+ "flex-shrink-0 transition-colors [&_svg]:w-4 [&_svg]:h-4",
213
+ shouldHighlight && !item.disabled ? "text-blue-600 dark:text-blue-400" : "text-gray-400 group-hover:text-blue-500 dark:text-gray-500 dark:group-hover:text-blue-400",
214
+ item.disabled && "group-hover:text-gray-400"
215
+ ),
216
+ children: item.icon
217
+ }
218
+ ),
219
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_framer_motion.AnimatePresence, { children: !isSidebarCollapsed && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
220
+ import_framer_motion.motion.span,
221
+ {
222
+ initial: { opacity: 0, width: 0 },
223
+ animate: { opacity: 1, width: "auto" },
224
+ exit: { opacity: 0, width: 0 },
225
+ transition: { duration: 0.2 },
226
+ className: "truncate",
227
+ children: item.label
228
+ }
229
+ ) })
230
+ ]
231
+ }
232
+ ),
233
+ !isSidebarCollapsed && hasSubItems && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
234
+ "span",
235
+ {
236
+ className: cn(
237
+ "flex-shrink-0 ml-2 transition-transform duration-200",
238
+ shouldHighlight ? "text-blue-500" : "text-gray-400"
239
+ ),
240
+ children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronDown, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronRight, { size: 16 })
241
+ }
242
+ )
243
+ ]
244
+ }
245
+ ),
246
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_framer_motion.AnimatePresence, { initial: false, children: !isSidebarCollapsed && hasSubItems && isExpanded && !item.disabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
247
+ import_framer_motion.motion.div,
248
+ {
249
+ initial: { height: 0, opacity: 0 },
250
+ animate: { height: "auto", opacity: 1 },
251
+ exit: { height: 0, opacity: 0 },
252
+ transition: { duration: 0.2 },
253
+ className: "overflow-hidden",
254
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative ml-6 mt-1 space-y-1", children: [
255
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute left-0 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-800" }),
256
+ item.subItems.filter((sub) => !!sub && !sub.hidden).map((subItem, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
257
+ SubItem,
258
+ {
259
+ item: subItem,
260
+ parentDisabled: item.disabled
261
+ },
262
+ index
263
+ ))
264
+ ] })
265
+ }
266
+ ) })
267
+ ] });
268
+ };
269
+ var SubItem = ({
270
+ item,
271
+ parentDisabled
272
+ }) => {
273
+ const location = (0, import_react_router_dom.useLocation)();
274
+ const navigate = (0, import_react_router_dom.useNavigate)();
275
+ const isActive = isPathActive(item.path, location.pathname);
276
+ const isDisabled = item.disabled || parentDisabled;
277
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
278
+ "button",
279
+ {
280
+ onClick: () => !isDisabled && item.path && navigate(item.path),
281
+ disabled: isDisabled,
282
+ className: cn(
283
+ "relative w-full flex items-center px-3 py-2 pl-6 rounded-lg text-sm transition-colors duration-200",
284
+ isActive && !isDisabled ? "bg-blue-100/50 text-blue-700 font-medium dark:bg-blue-900/30 dark:text-blue-400" : "text-gray-500 hover:bg-gray-50 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200",
285
+ isDisabled && "opacity-50 cursor-not-allowed grayscale-[0.5]"
286
+ ),
287
+ children: [
288
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "truncate", children: item.label }),
289
+ isActive && !isDisabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute left-0 top-1/2 -translate-y-1/2 w-1 h-4 bg-blue-500 rounded-r-full" })
290
+ ]
291
+ }
292
+ );
293
+ };
294
+ var DashboardLayout = ({
295
+ children,
296
+ navItems,
297
+ title = "Dashboard",
298
+ logo,
299
+ userProfile,
300
+ fontFamily = 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"'
301
+ // Humanist System Stack
302
+ }) => {
303
+ const isDesktop = useMediaQuery("(min-width: 1024px)");
304
+ const location = (0, import_react_router_dom.useLocation)();
305
+ const navigate = (0, import_react_router_dom.useNavigate)();
306
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react.useState)(true);
307
+ const [expandedMenus, setExpandedMenus] = (0, import_react.useState)(
308
+ () => {
309
+ const initialState = {};
310
+ navItems.forEach((item) => {
311
+ if (item && !item.hidden && !item.disabled && item.subItems?.some(
312
+ (sub) => sub && !sub.hidden && isPathActive(sub.path, location.pathname)
313
+ )) {
314
+ initialState[item.label] = true;
315
+ }
316
+ });
317
+ return initialState;
318
+ }
319
+ );
320
+ const prevPathRef = (0, import_react.useRef)(location.pathname);
321
+ (0, import_react.useEffect)(() => {
322
+ if (prevPathRef.current !== location.pathname) {
323
+ const activeItem = navItems.find(
324
+ (item) => !!item && !item.hidden && !item.disabled && item.subItems?.some(
325
+ (sub) => sub && !sub.hidden && isPathActive(sub.path, location.pathname)
326
+ ) === true
327
+ );
328
+ if (activeItem) {
329
+ setExpandedMenus((prev) => ({ ...prev, [activeItem.label]: true }));
330
+ }
331
+ prevPathRef.current = location.pathname;
332
+ }
333
+ }, [location.pathname, navItems]);
334
+ const isCollapsed = isDesktop && !isSidebarOpen;
335
+ (0, import_react.useEffect)(() => {
336
+ if (!isDesktop) {
337
+ setIsSidebarOpen(false);
338
+ } else {
339
+ setIsSidebarOpen(true);
340
+ }
341
+ }, [isDesktop]);
342
+ const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen);
343
+ const toggleMenu = (label) => {
344
+ if (isCollapsed) {
345
+ setIsSidebarOpen(true);
346
+ setTimeout(() => {
347
+ setExpandedMenus((prev) => {
348
+ const isCurrentlyOpen = !!prev[label];
349
+ return isCurrentlyOpen ? {} : { [label]: true };
350
+ });
351
+ }, 50);
352
+ return;
353
+ }
354
+ setExpandedMenus((prev) => {
355
+ const isCurrentlyOpen = !!prev[label];
356
+ return isCurrentlyOpen ? {} : { [label]: true };
357
+ });
358
+ };
359
+ const sidebarVariants = {
360
+ desktopOpen: {
361
+ width: "16rem",
362
+ transition: { duration: 0.3, type: "spring", bounce: 0, damping: 20 }
363
+ },
364
+ desktopClosed: {
365
+ width: "5rem",
366
+ // Mini Sidebar Width
367
+ transition: { duration: 0.3, type: "spring", bounce: 0, damping: 20 }
368
+ },
369
+ mobileOpen: {
370
+ x: 0,
371
+ transition: { duration: 0.3, type: "spring", bounce: 0, damping: 20 }
372
+ },
373
+ mobileClosed: {
374
+ x: "-100%",
375
+ transition: { duration: 0.3, type: "spring", bounce: 0, damping: 20 }
376
+ }
377
+ };
378
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
379
+ "div",
380
+ {
381
+ className: "min-h-screen bg-gray-50 dark:bg-[#0B0F1A] text-slate-900 dark:text-slate-100 flex transition-colors duration-500 font-sans overflow-hidden",
382
+ style: { fontFamily },
383
+ children: [
384
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_framer_motion.AnimatePresence, { children: !isDesktop && isSidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
385
+ import_framer_motion.motion.div,
386
+ {
387
+ initial: { opacity: 0 },
388
+ animate: { opacity: 0.5 },
389
+ exit: { opacity: 0 },
390
+ onClick: () => setIsSidebarOpen(false),
391
+ className: "fixed inset-0 bg-black/50 z-40 lg:hidden backdrop-blur-sm"
392
+ }
393
+ ) }),
394
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
395
+ import_framer_motion.motion.aside,
396
+ {
397
+ className: "fixed lg:relative inset-y-0 left-0 z-50 bg-white dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 flex flex-col h-screen",
398
+ initial: isDesktop ? "desktopOpen" : "mobileClosed",
399
+ animate: isDesktop ? isSidebarOpen ? "desktopOpen" : "desktopClosed" : isSidebarOpen ? "mobileOpen" : "mobileClosed",
400
+ variants: sidebarVariants,
401
+ children: [
402
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
403
+ "div",
404
+ {
405
+ className: cn(
406
+ "h-16 flex items-center border-b border-gray-100 dark:border-gray-800 flex-shrink-0 overflow-hidden transition-all duration-300",
407
+ isCollapsed ? "justify-center px-0" : "px-6"
408
+ ),
409
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center gap-2 text-blue-600 dark:text-blue-400", children: isCollapsed ? logo : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
410
+ logo,
411
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-bold text-lg tracking-tight text-gray-900 dark:text-white", children: title })
412
+ ] }) })
413
+ }
414
+ ),
415
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 p-4 overflow-y-auto overflow-x-hidden scrollbar-hide", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("nav", { className: "space-y-1", children: navItems.filter((item) => !!item && !item.hidden).map((item) => {
416
+ const isActive = isPathActive(item.path, location.pathname);
417
+ const isChildActive = item.subItems?.some(
418
+ (sub) => sub && !sub.hidden && isPathActive(sub.path, location.pathname)
419
+ );
420
+ const isExpanded = expandedMenus[item.label];
421
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
422
+ SidebarItem,
423
+ {
424
+ item,
425
+ isActive,
426
+ isChildActive: !!isChildActive,
427
+ isExpanded: !!isExpanded,
428
+ isSidebarCollapsed: !!isCollapsed,
429
+ onClick: () => {
430
+ if (item.path) navigate(item.path);
431
+ if (isCollapsed && !item.path) {
432
+ setIsSidebarOpen(true);
433
+ }
434
+ },
435
+ onToggleExpand: () => toggleMenu(item.label)
436
+ },
437
+ item.label
438
+ );
439
+ }) }) })
440
+ ]
441
+ }
442
+ ),
443
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 flex flex-col min-w-0 h-screen overflow-hidden", children: [
444
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "sticky top-0 z-30 h-16 bg-white/80 dark:bg-gray-900/80 backdrop-blur-md border-b border-gray-200 dark:border-gray-800 px-4 sm:px-6 flex items-center justify-between flex-shrink-0", children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
446
+ "button",
447
+ {
448
+ onClick: toggleSidebar,
449
+ className: "p-2 -ml-2 rounded-lg text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800 transition-colors",
450
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Menu, { size: 20 })
451
+ }
452
+ ) }),
453
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center gap-2", children: userProfile && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
454
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-px h-6 mx-2 bg-gray-200 dark:bg-gray-800" }),
455
+ userProfile
456
+ ] }) })
457
+ ] }),
458
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("main", { className: "flex-1 p-2 md:p-4 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "max-w-7xl mx-auto", children }) })
459
+ ] })
460
+ ]
461
+ }
462
+ );
463
+ };
464
+
465
+ // src/components/ThemeToggle.tsx
466
+ var import_lucide_react2 = require("lucide-react");
467
+
468
+ // src/hooks/ThemeContext.tsx
469
+ var import_react2 = require("react");
470
+ var import_jsx_runtime3 = require("react/jsx-runtime");
471
+ var ThemeContext = (0, import_react2.createContext)(void 0);
472
+ var ThemeProvider = ({ children }) => {
473
+ const [isDarkMode, setIsDarkMode] = (0, import_react2.useState)(() => {
474
+ if (typeof window !== "undefined") {
475
+ const savedTheme = localStorage.getItem("theme");
476
+ if (savedTheme) {
477
+ return savedTheme === "dark";
478
+ }
479
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
480
+ }
481
+ return false;
482
+ });
483
+ (0, import_react2.useEffect)(() => {
484
+ const root = window.document.documentElement;
485
+ if (isDarkMode) {
486
+ root.classList.add("dark");
487
+ localStorage.setItem("theme", "dark");
488
+ } else {
489
+ root.classList.remove("dark");
490
+ localStorage.setItem("theme", "light");
491
+ }
492
+ }, [isDarkMode]);
493
+ const toggleTheme = () => setIsDarkMode((prev) => !prev);
494
+ const setTheme = (theme) => setIsDarkMode(theme === "dark");
495
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ThemeContext.Provider, { value: { isDarkMode, toggleTheme, setTheme }, children });
496
+ };
497
+ var useTheme = () => {
498
+ const context = (0, import_react2.useContext)(ThemeContext);
499
+ if (context === void 0) {
500
+ throw new Error("useTheme must be used within a ThemeProvider");
501
+ }
502
+ return context;
503
+ };
504
+
505
+ // src/components/ThemeToggle.tsx
506
+ var import_jsx_runtime4 = require("react/jsx-runtime");
507
+ var ThemeToggle = ({
508
+ className
509
+ }) => {
510
+ const { isDarkMode, toggleTheme } = useTheme();
511
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
512
+ "button",
513
+ {
514
+ onClick: toggleTheme,
515
+ className: cn(
516
+ "p-2 rounded-lg transition-all duration-200",
517
+ "text-slate-500 hover:text-blue-600 hover:bg-slate-100",
518
+ "dark:text-yellow-400 dark:hover:text-yellow-300 dark:hover:bg-slate-800",
519
+ className
520
+ ),
521
+ "aria-label": "Toggle dark mode",
522
+ children: isDarkMode ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
523
+ import_lucide_react2.Sun,
524
+ {
525
+ size: 20,
526
+ className: "stroke-2 transition-transform duration-300 rotate-0 scale-100"
527
+ }
528
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
529
+ import_lucide_react2.Moon,
530
+ {
531
+ size: 20,
532
+ className: "stroke-2 transition-transform duration-300 rotate-0 scale-100"
533
+ }
534
+ )
535
+ }
536
+ );
537
+ };
538
+
539
+ // src/hooks/useTheme.ts
540
+ var import_react3 = require("react");
541
+
542
+ // src/components/LoadingBox.tsx
543
+ var import_jsx_runtime5 = require("react/jsx-runtime");
544
+ var LoadingBox = () => {
545
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "animate-spin rounded-full h-32 w-32 border-b-2 border-primary", children: "aaa" }) }) });
546
+ };
547
+
548
+ // src/components/spins/ClassicSpin.tsx
549
+ var import_lucide_react3 = require("lucide-react");
550
+ var import_jsx_runtime6 = require("react/jsx-runtime");
551
+ var ClassicSpin = ({ msg = "Please wait..." }) => {
552
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-0 z-50 flex flex-col items-center justify-center bg-white/30 dark:bg-zinc-900/30 backdrop-blur-[0.5px] transition-all duration-200", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col items-center justify-center p-6 bg-white dark:bg-zinc-800 rounded-2xl shadow-2xl border border-gray-100 dark:border-zinc-700 animate-in zoom-in-95 duration-200", children: [
553
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative", children: [
554
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-0 bg-indigo-500 blur-lg opacity-20 animate-pulse" }),
555
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Loader2, { className: "h-8 w-8 animate-spin text-indigo-600 dark:text-indigo-400 relative z-10" })
556
+ ] }),
557
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-3 text-sm font-medium text-gray-900 dark:text-white", children: msg })
558
+ ] }) });
559
+ };
560
+
561
+ // src/components/spins/OverlaySpin.tsx
562
+ var import_jsx_runtime7 = require("react/jsx-runtime");
563
+ var OverlaySpin = ({ msg = "Processing..." }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-0 bg-white/50 dark:bg-black/50 backdrop-blur-[1px] z-50 flex items-center justify-center rounded-xl transition-all duration-300", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col items-center gap-2 bg-white dark:bg-zinc-800 p-4 rounded-xl shadow-xl border border-gray-100 dark:border-zinc-700", children: [
564
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "w-6 h-6 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-xs font-medium text-gray-500 animate-pulse", children: msg })
566
+ ] }) });
567
+
568
+ // src/components/spins/LoadingSpin.tsx
569
+ var import_jsx_runtime8 = require("react/jsx-runtime");
570
+ var LoadingSpin = ({
571
+ className,
572
+ size = "md",
573
+ color = "text-current"
574
+ }) => {
575
+ const sizeClasses = {
576
+ sm: "h-4 w-4",
577
+ md: "h-6 w-6",
578
+ lg: "h-10 w-10"
579
+ };
580
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
581
+ "svg",
582
+ {
583
+ className: cn("animate-spin", sizeClasses[size], color, className),
584
+ fill: "none",
585
+ viewBox: "0 0 24 24",
586
+ xmlns: "http://www.w3.org/2000/svg",
587
+ children: [
588
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
589
+ "circle",
590
+ {
591
+ className: "opacity-25",
592
+ cx: "12",
593
+ cy: "12",
594
+ r: "10",
595
+ stroke: "currentColor",
596
+ strokeWidth: "4"
597
+ }
598
+ ),
599
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
600
+ "path",
601
+ {
602
+ className: "opacity-75",
603
+ fill: "currentColor",
604
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
605
+ }
606
+ )
607
+ ]
608
+ }
609
+ );
610
+ };
611
+
612
+ // src/components/CodeBlock.tsx
613
+ var import_react4 = require("react");
614
+ var import_lucide_react4 = require("lucide-react");
615
+ var import_jsx_runtime9 = require("react/jsx-runtime");
616
+ var CodeBlock = ({
617
+ code,
618
+ language = "tsx",
619
+ className
620
+ }) => {
621
+ const [copied, setCopied] = (0, import_react4.useState)(false);
622
+ const handleCopy = () => {
623
+ navigator.clipboard.writeText(code);
624
+ setCopied(true);
625
+ setTimeout(() => setCopied(false), 2e3);
626
+ };
627
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
628
+ "div",
629
+ {
630
+ className: cn(
631
+ "relative group rounded-2xl overflow-hidden border border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-black/50 backdrop-blur-sm",
632
+ className
633
+ ),
634
+ children: [
635
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-zinc-900/50 border-b border-gray-200 dark:border-gray-800", children: [
636
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-gray-400", children: language }),
637
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
638
+ "button",
639
+ {
640
+ onClick: handleCopy,
641
+ className: "p-1.5 rounded-lg text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-white dark:hover:bg-zinc-800 transition-all duration-200",
642
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Check, { size: 14, className: "text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Copy, { size: 14 })
643
+ }
644
+ )
645
+ ] }),
646
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "p-4 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("pre", { className: "text-sm font-mono leading-relaxed text-gray-800 dark:text-gray-300", children: code }) })
647
+ ]
648
+ }
649
+ );
650
+ };
651
+
652
+ // src/components/Card.tsx
653
+ var import_jsx_runtime10 = require("react/jsx-runtime");
654
+ var Card = ({
655
+ children,
656
+ className,
657
+ variant = "default",
658
+ ...props
659
+ }) => {
660
+ const variants = {
661
+ default: "bg-white dark:bg-zinc-900 border-gray-200 dark:border-zinc-800 shadow-sm",
662
+ flat: "bg-gray-50/50 dark:bg-zinc-950/50 border-gray-100 dark:border-zinc-900",
663
+ glass: "bg-white/70 dark:bg-black/40 backdrop-blur-md border-white/20 dark:border-white/5 shadow-xl"
664
+ };
665
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
666
+ "div",
667
+ {
668
+ className: cn(
669
+ "rounded-[2rem] border p-6 transition-all duration-300",
670
+ variants[variant],
671
+ className
672
+ ),
673
+ ...props,
674
+ children
675
+ }
676
+ );
677
+ };
678
+ var CardHeader = ({
679
+ children,
680
+ className
681
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("mb-4 space-y-1.5", className), children });
682
+ var CardTitle = ({
683
+ children,
684
+ className
685
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
686
+ "h3",
687
+ {
688
+ className: cn(
689
+ "text-lg font-semibold leading-none tracking-tight text-gray-900 dark:text-gray-100",
690
+ className
691
+ ),
692
+ children
693
+ }
694
+ );
695
+ var CardDescription = ({
696
+ children,
697
+ className
698
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: cn("text-sm text-gray-500 dark:text-gray-400", className), children });
699
+ var CardContent = ({
700
+ children,
701
+ className
702
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("", className), children });
703
+ var CardFooter = ({
704
+ children,
705
+ className
706
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("mt-6 flex items-center pt-0", className), children });
707
+ Card.Header = CardHeader;
708
+ Card.Title = CardTitle;
709
+ Card.Description = CardDescription;
710
+ Card.Content = CardContent;
711
+ Card.Footer = CardFooter;
712
+
713
+ // src/components/modal/Modal.tsx
714
+ var import_lucide_react5 = require("lucide-react");
715
+ var import_framer_motion2 = require("framer-motion");
716
+ var import_jsx_runtime11 = require("react/jsx-runtime");
717
+ var Modal = ({
718
+ isOpen,
719
+ onClose,
720
+ title,
721
+ children,
722
+ isLoading = false,
723
+ width = 500
724
+ }) => {
725
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_framer_motion2.AnimatePresence, { children: isOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "fixed inset-0 z-[1000] flex items-center justify-center p-4 sm:p-6", children: [
726
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
727
+ import_framer_motion2.motion.div,
728
+ {
729
+ initial: { opacity: 0 },
730
+ animate: { opacity: 1 },
731
+ exit: { opacity: 0 },
732
+ onClick: isLoading ? void 0 : onClose,
733
+ className: "fixed inset-0 bg-black/40 backdrop-blur-sm transition-all"
734
+ }
735
+ ),
736
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
737
+ import_framer_motion2.motion.div,
738
+ {
739
+ initial: { opacity: 0, scale: 0.95, y: 10 },
740
+ animate: { opacity: 1, scale: 1, y: 0 },
741
+ exit: { opacity: 0, scale: 0.95, y: 10 },
742
+ transition: { type: "spring", duration: 0.3 },
743
+ style: { maxWidth: width },
744
+ className: "w-full bg-white dark:bg-zinc-900 rounded-[2rem] shadow-2xl border border-gray-200 dark:border-white/5 overflow-hidden relative z-10 flex flex-col max-h-[90vh]",
745
+ children: [
746
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "px-8 py-5 border-b border-gray-100 dark:border-white/5 flex items-center justify-between bg-white/50 dark:bg-zinc-900/50 backdrop-blur-xl sticky top-0 z-20", children: [
747
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "text-xl font-bold text-gray-900 dark:text-white tracking-tight", children: title }),
748
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
749
+ "button",
750
+ {
751
+ onClick: onClose,
752
+ disabled: isLoading,
753
+ className: "p-2 -mr-2 rounded-full text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-white/5 transition-all disabled:opacity-50",
754
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.X, { size: 20 })
755
+ }
756
+ )
757
+ ] }),
758
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-blue-500 via-indigo-600 to-purple-500 opacity-60" }),
759
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "p-8 overflow-y-auto relative flex-1", children: [
760
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ClassicSpin, {}),
761
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
762
+ "div",
763
+ {
764
+ className: isLoading ? "opacity-20 blur-sm transition-all" : "transition-all",
765
+ children
766
+ }
767
+ )
768
+ ] })
769
+ ]
770
+ }
771
+ )
772
+ ] }) });
773
+ };
774
+
775
+ // src/components/PageHeader.tsx
776
+ var import_jsx_runtime12 = require("react/jsx-runtime");
777
+ var PageHeader = ({
778
+ title,
779
+ description,
780
+ children,
781
+ className
782
+ }) => {
783
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cn("space-y-2 mb-8", className), children: [
784
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between", children: [
785
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h1", { className: "text-3xl font-bold text-gray-900 dark:text-white tracking-tight", children: title }),
786
+ children
787
+ ] }),
788
+ description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-gray-500 dark:text-gray-400 max-w-2xl leading-relaxed", children: description })
789
+ ] });
790
+ };
791
+
792
+ // src/hooks/useModal.tsx
793
+ var import_react5 = require("react");
794
+ var useModal = (initialState = false) => {
795
+ const [isOpen, setIsOpen] = (0, import_react5.useState)(initialState);
796
+ const [state, setState] = (0, import_react5.useState)(null);
797
+ const open = (0, import_react5.useCallback)(() => setIsOpen(true), []);
798
+ const close = (0, import_react5.useCallback)(() => {
799
+ setIsOpen(false);
800
+ setState(null);
801
+ }, []);
802
+ const toggle = (0, import_react5.useCallback)(() => setIsOpen((prev) => !prev), []);
803
+ const openState = (0, import_react5.useCallback)((data) => {
804
+ setState(data);
805
+ open();
806
+ }, []);
807
+ return {
808
+ isOpen,
809
+ open,
810
+ close,
811
+ toggle,
812
+ openState,
813
+ state,
814
+ Modal
815
+ };
816
+ };
817
+
818
+ // src/components/Fields/Input.tsx
819
+ var import_react7 = require("react");
820
+ var import_lucide_react6 = require("lucide-react");
821
+
822
+ // src/providers/WarqadProvider.tsx
823
+ var import_react6 = require("react");
824
+ var import_jsx_runtime13 = require("react/jsx-runtime");
825
+ var WarqadConfigContext = (0, import_react6.createContext)(
826
+ void 0
827
+ );
828
+ var useWarqadConfig = () => {
829
+ const context = (0, import_react6.useContext)(WarqadConfigContext);
830
+ if (context === void 0) {
831
+ throw new Error("useWarqadConfig must be used within a WarqadProvider");
832
+ }
833
+ return context.config;
834
+ };
835
+ var WarqadProvider = ({
836
+ children,
837
+ config = { apiUrl: "/api" }
838
+ }) => {
839
+ const mergedConfig = {
840
+ apiUrl: "/api",
841
+ ...config,
842
+ theme: {
843
+ primaryColor: "#3b82f6",
844
+ // Default blue-500
845
+ ...config?.theme
846
+ }
847
+ };
848
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(WarqadConfigContext.Provider, { value: { config: mergedConfig }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
849
+ "div",
850
+ {
851
+ style: {
852
+ "--primary-color": mergedConfig.theme?.primaryColor
853
+ },
854
+ children
855
+ }
856
+ ) }) });
857
+ };
858
+
859
+ // src/components/Fields/Input.tsx
860
+ var import_react_hook_form = require("react-hook-form");
861
+ var import_jsx_runtime14 = require("react/jsx-runtime");
862
+ var Input = (0, import_react7.forwardRef)(
863
+ ({
864
+ label,
865
+ icon,
866
+ error,
867
+ containerClassName = "",
868
+ name,
869
+ form,
870
+ onFocus,
871
+ onBlur,
872
+ className = "",
873
+ type,
874
+ ...props
875
+ }, ref) => {
876
+ const [isFocused, setIsFocused] = (0, import_react7.useState)(false);
877
+ const [showPassword, setShowPassword] = (0, import_react7.useState)(false);
878
+ const { theme } = useWarqadConfig();
879
+ const primaryColor = theme?.primaryColor;
880
+ let message = error;
881
+ if (form && name) {
882
+ const {
883
+ formState: { errors }
884
+ } = form;
885
+ const errorObj = name.split(".").reduce((acc, current) => acc?.[current], errors);
886
+ message = errorObj?.message;
887
+ }
888
+ (0, import_react7.useEffect)(() => {
889
+ if (form && name) {
890
+ form.clearErrors("root");
891
+ }
892
+ }, [form?.watch(name)]);
893
+ const renderInput = (inputProps, localType = type || "text") => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `space-y-2 group ${containerClassName}`, children: [
894
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
895
+ "label",
896
+ {
897
+ htmlFor: props.id,
898
+ className: `block capitalize text-xs font-medium transition-colors duration-200`,
899
+ style: { color: isFocused ? primaryColor : void 0 },
900
+ children: [
901
+ label,
902
+ props.required && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
903
+ ]
904
+ }
905
+ ),
906
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "relative", children: [
907
+ icon && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
908
+ "div",
909
+ {
910
+ className: `transition-colors duration-200`,
911
+ style: { color: isFocused ? primaryColor : "#9ca3af" },
912
+ children: icon
913
+ }
914
+ ) }),
915
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
916
+ "input",
917
+ {
918
+ ref,
919
+ onFocus: (e) => {
920
+ setIsFocused(true);
921
+ onFocus?.(e);
922
+ },
923
+ onBlur: (e) => {
924
+ setIsFocused(false);
925
+ onBlur?.(e);
926
+ },
927
+ className: `block w-full ${icon ? "pl-10" : "pl-3"} pr-3 h-8 py-0 rounded-lg border-gray-200 dark:border-zinc-800 bg-gray-50 dark:bg-zinc-900/50 text-gray-900 dark:text-white placeholder-gray-400 focus:bg-white dark:focus:bg-zinc-900 outline-none transition-all duration-200 border text-sm ${className}`,
928
+ style: {
929
+ borderColor: isFocused ? primaryColor : void 0,
930
+ boxShadow: isFocused ? `${primaryColor}33 0px 0px 0px 2px` : void 0
931
+ },
932
+ ...props,
933
+ ...inputProps,
934
+ type: localType === "password" ? showPassword ? "text" : "password" : localType
935
+ }
936
+ ),
937
+ type === "password" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
938
+ "button",
939
+ {
940
+ type: "button",
941
+ onClick: () => setShowPassword(!showPassword),
942
+ className: "absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors focus:outline-none cursor-pointer",
943
+ tabIndex: -1,
944
+ children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react6.EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react6.Eye, { className: "h-5 w-5" })
945
+ }
946
+ )
947
+ ] }),
948
+ message && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
949
+ ] });
950
+ if (form && name && type === "number") {
951
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
952
+ import_react_hook_form.Controller,
953
+ {
954
+ control: form.control,
955
+ name,
956
+ render: ({ field: { onChange, value, ref: fieldRef, onBlur: onBlur2 } }) => renderInput(
957
+ {
958
+ ref: fieldRef,
959
+ onBlur: () => {
960
+ onBlur2();
961
+ },
962
+ value: value ? String(value).split(".").map(
963
+ (part, index) => index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
964
+ ).join(".") : "",
965
+ onChange: (e) => {
966
+ const rawValue = e.target.value.replace(/,/g, "");
967
+ if (!/^\d*\.?\d*$/.test(rawValue)) return;
968
+ if (rawValue === "") {
969
+ onChange("");
970
+ } else {
971
+ const numValue = Number(rawValue);
972
+ if (!isNaN(numValue) && String(numValue) === rawValue) {
973
+ onChange(numValue);
974
+ } else {
975
+ onChange(rawValue);
976
+ }
977
+ }
978
+ props.onChange?.(e);
979
+ }
980
+ },
981
+ "text"
982
+ )
983
+ }
984
+ );
985
+ }
986
+ return renderInput(
987
+ form && name ? form.register(name, type === "number" ? { valueAsNumber: true } : {}) : {}
988
+ );
989
+ }
990
+ );
991
+
992
+ // src/components/Fields/PhoneInput.tsx
993
+ var import_react8 = require("react");
994
+ var import_react_phone_number_input = __toESM(require("react-phone-number-input"));
995
+ var import_style = require("react-phone-number-input/style.css");
996
+ var import_react_hook_form2 = require("react-hook-form");
997
+ var import_jsx_runtime15 = require("react/jsx-runtime");
998
+ var PhoneInput = (0, import_react8.forwardRef)(
999
+ ({
1000
+ label,
1001
+ icon,
1002
+ error,
1003
+ containerClassName = "",
1004
+ name,
1005
+ form,
1006
+ onChange,
1007
+ value,
1008
+ className = "",
1009
+ ...props
1010
+ }, ref) => {
1011
+ const [isFocused, setIsFocused] = (0, import_react8.useState)(false);
1012
+ const { theme } = useWarqadConfig();
1013
+ const primaryColor = theme?.primaryColor;
1014
+ let message = error;
1015
+ if (form && name) {
1016
+ const {
1017
+ formState: { errors }
1018
+ } = form;
1019
+ const nameParts = name.split(".");
1020
+ let currentError = errors;
1021
+ for (const part of nameParts) {
1022
+ currentError = currentError?.[part];
1023
+ }
1024
+ message = currentError?.message || message;
1025
+ }
1026
+ const renderInput = (onChangeHandler, currentValue) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `space-y-2 group ${containerClassName}`, children: [
1027
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1028
+ "label",
1029
+ {
1030
+ className: `block text-xs font-medium transition-colors duration-200`,
1031
+ style: {
1032
+ color: isFocused || currentValue ? primaryColor : void 0
1033
+ },
1034
+ children: [
1035
+ label,
1036
+ props.required && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
1037
+ ]
1038
+ }
1039
+ ),
1040
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "relative", children: [
1041
+ icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none z-10", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1042
+ "div",
1043
+ {
1044
+ className: `transition-colors duration-200`,
1045
+ style: { color: isFocused ? primaryColor : "#9ca3af" },
1046
+ children: icon
1047
+ }
1048
+ ) }),
1049
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1050
+ import_react_phone_number_input.default,
1051
+ {
1052
+ ref,
1053
+ defaultCountry: "KE",
1054
+ international: true,
1055
+ withCountryCallingCode: true,
1056
+ value: currentValue,
1057
+ onChange: (val) => onChangeHandler(val),
1058
+ onFocus: () => setIsFocused(true),
1059
+ onBlur: () => setIsFocused(false),
1060
+ className: `block w-full rounded-lg border-gray-200 dark:border-zinc-800 bg-gray-50 dark:bg-zinc-900/50 text-gray-900 dark:text-white placeholder-gray-400 focus-within:bg-white dark:focus-within:bg-zinc-900 outline-none transition-all duration-200 border [&_.PhoneInputInput]:bg-transparent [&_.PhoneInputInput]:outline-none [&_.PhoneInputInput]:text-sm [&_.PhoneInputCountry]:mr-2 ${icon ? "pl-10" : "pl-3"} pr-3 h-8 py-0 ${className}`,
1061
+ style: {
1062
+ borderColor: isFocused ? primaryColor : void 0,
1063
+ boxShadow: isFocused ? `${primaryColor}33 0px 0px 0px 2px` : void 0
1064
+ },
1065
+ ...props
1066
+ }
1067
+ )
1068
+ ] }),
1069
+ message && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
1070
+ ] });
1071
+ if (form && name) {
1072
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1073
+ import_react_hook_form2.Controller,
1074
+ {
1075
+ name,
1076
+ control: form.control,
1077
+ rules: {
1078
+ validate: (value2) => value2 && (0, import_react_phone_number_input.isValidPhoneNumber)(value2) ? true : "Invalid phone number"
1079
+ },
1080
+ render: ({ field: { onChange: onChange2, value: value2 } }) => renderInput(onChange2, value2)
1081
+ }
1082
+ );
1083
+ }
1084
+ return renderInput(onChange || (() => {
1085
+ }), value || "");
1086
+ }
1087
+ );
1088
+ PhoneInput.displayName = "PhoneInput";
1089
+
1090
+ // src/components/Fields/select.tsx
1091
+ var import_react9 = require("react");
1092
+ var import_lucide_react7 = require("lucide-react");
1093
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1094
+ var Select = (0, import_react9.forwardRef)(
1095
+ ({
1096
+ label,
1097
+ options,
1098
+ icon,
1099
+ error,
1100
+ containerClassName = "",
1101
+ name,
1102
+ form,
1103
+ onChange,
1104
+ onFocus,
1105
+ onBlur,
1106
+ className = "",
1107
+ ...props
1108
+ }, ref) => {
1109
+ const [isFocused, setIsFocused] = (0, import_react9.useState)(false);
1110
+ const { theme } = useWarqadConfig();
1111
+ const primaryColor = theme?.primaryColor;
1112
+ let message = error;
1113
+ if (form) {
1114
+ const {
1115
+ formState: { errors }
1116
+ } = form;
1117
+ const nameI = name.split(".");
1118
+ const names = nameI.length > 1 ? nameI[1] : nameI[0];
1119
+ message = errors?.[names ? names : name]?.message;
1120
+ }
1121
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `space-y-2 group ${containerClassName}`, children: [
1122
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1123
+ "label",
1124
+ {
1125
+ htmlFor: props.id,
1126
+ className: `block text-xs font-medium transition-colors duration-200`,
1127
+ style: { color: isFocused ? primaryColor : void 0 },
1128
+ children: [
1129
+ label,
1130
+ props.required && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
1131
+ ]
1132
+ }
1133
+ ),
1134
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "relative", children: [
1135
+ icon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1136
+ "div",
1137
+ {
1138
+ className: `transition-colors duration-200`,
1139
+ style: { color: isFocused ? primaryColor : "#9ca3af" },
1140
+ children: icon
1141
+ }
1142
+ ) }),
1143
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1144
+ "select",
1145
+ {
1146
+ ref,
1147
+ onFocus: (e) => {
1148
+ setIsFocused(true);
1149
+ onFocus?.(e);
1150
+ },
1151
+ ...form ? form.register(name) : {},
1152
+ onBlur: (e) => {
1153
+ setIsFocused(false);
1154
+ onBlur?.(e);
1155
+ },
1156
+ onChange: (e) => {
1157
+ onChange?.(e.target.value);
1158
+ if (form) {
1159
+ form.setValue(name, e.target.value);
1160
+ }
1161
+ },
1162
+ className: `block w-full ${icon ? "pl-10" : "pl-3"} pr-10 h-8 py-0 rounded-lg border-gray-200 dark:border-zinc-800 bg-gray-50 dark:bg-zinc-900/50 text-gray-900 dark:text-white placeholder-gray-400 focus:bg-white dark:focus:bg-zinc-900 outline-none transition-all duration-200 border appearance-none text-sm ${className}`,
1163
+ style: {
1164
+ borderColor: isFocused ? primaryColor : void 0,
1165
+ boxShadow: isFocused ? `${primaryColor}33 0px 0px 0px 2px` : void 0
1166
+ },
1167
+ ...props,
1168
+ children: [
1169
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("option", { value: "", disabled: true, children: [
1170
+ "Select ",
1171
+ label
1172
+ ] }),
1173
+ options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1174
+ "option",
1175
+ {
1176
+ value: String(option.value),
1177
+ disabled: option.disabled,
1178
+ children: option.label
1179
+ },
1180
+ String(option.value)
1181
+ ))
1182
+ ]
1183
+ }
1184
+ ),
1185
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react7.ChevronDown, { className: "h-4 w-4 text-gray-400" }) })
1186
+ ] }),
1187
+ message && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
1188
+ ] });
1189
+ }
1190
+ );
1191
+ Select.displayName = "Select";
1192
+
1193
+ // src/components/Fields/textArea.tsx
1194
+ var import_react10 = require("react");
1195
+ var import_react_hook_form3 = require("react-hook-form");
1196
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1197
+ var Textarea = (0, import_react10.forwardRef)(
1198
+ ({
1199
+ label,
1200
+ error,
1201
+ containerClassName = "",
1202
+ name,
1203
+ form,
1204
+ onFocus,
1205
+ onBlur,
1206
+ className = "",
1207
+ ...props
1208
+ }, ref) => {
1209
+ const [isFocused, setIsFocused] = (0, import_react10.useState)(false);
1210
+ const { theme } = useWarqadConfig();
1211
+ const primaryColor = theme?.primaryColor;
1212
+ let message = error;
1213
+ if (form && name) {
1214
+ const {
1215
+ formState: { errors }
1216
+ } = form;
1217
+ const errorObj = name.split(".").reduce((acc, current) => acc?.[current], errors);
1218
+ message = errorObj?.message;
1219
+ }
1220
+ const renderInput = (inputProps, ref2) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: `space-y-2 group ${containerClassName}`, children: [
1221
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1222
+ "label",
1223
+ {
1224
+ htmlFor: props.id,
1225
+ className: `block capitalize text-xs font-medium transition-colors duration-200`,
1226
+ style: { color: isFocused ? primaryColor : void 0 },
1227
+ children: [
1228
+ label,
1229
+ props.required && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
1230
+ ]
1231
+ }
1232
+ ),
1233
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1234
+ "textarea",
1235
+ {
1236
+ ref: ref2,
1237
+ onFocus: (e) => {
1238
+ setIsFocused(true);
1239
+ onFocus?.(e);
1240
+ },
1241
+ onBlur: (e) => {
1242
+ setIsFocused(false);
1243
+ onBlur?.(e);
1244
+ },
1245
+ className: `block w-full px-3 py-3 rounded-lg border-gray-200 dark:border-zinc-800 bg-gray-50 dark:bg-zinc-900/50 text-gray-900 dark:text-white placeholder-gray-400 focus:bg-white dark:focus:bg-zinc-900 outline-none transition-all duration-200 border min-h-[100px] resize-none text-sm ${className}`,
1246
+ style: {
1247
+ borderColor: isFocused ? primaryColor : void 0,
1248
+ boxShadow: isFocused ? `${primaryColor}33 0px 0px 0px 2px` : void 0
1249
+ },
1250
+ ...props,
1251
+ ...inputProps
1252
+ }
1253
+ ) }),
1254
+ message && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
1255
+ ] });
1256
+ if (form && name) {
1257
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1258
+ import_react_hook_form3.Controller,
1259
+ {
1260
+ control: form.control,
1261
+ name,
1262
+ render: ({ field: { onChange, value, ref: fieldRef, onBlur: onBlur2 } }) => renderInput(
1263
+ {
1264
+ value: value || "",
1265
+ // Ensure controlled input doesn't warn about uncontrolled
1266
+ onChange: (e) => {
1267
+ onChange(e);
1268
+ props.onChange?.(e);
1269
+ },
1270
+ onBlur: () => {
1271
+ onBlur2();
1272
+ }
1273
+ },
1274
+ fieldRef
1275
+ )
1276
+ }
1277
+ );
1278
+ }
1279
+ return renderInput({}, ref);
1280
+ }
1281
+ );
1282
+
1283
+ // src/components/Fields/searchApi.tsx
1284
+ var import_react12 = require("react");
1285
+ var import_lucide_react8 = require("lucide-react");
1286
+
1287
+ // src/hooks/Fetches/useApis.tsx
1288
+ var import_react11 = require("react");
1289
+ var import_axios = __toESM(require("axios"));
1290
+ var useApi = () => {
1291
+ const { apiUrl } = useWarqadConfig();
1292
+ const api = (0, import_react11.useMemo)(
1293
+ () => import_axios.default.create({
1294
+ baseURL: apiUrl || "/api",
1295
+ withCredentials: true
1296
+ }),
1297
+ [apiUrl]
1298
+ );
1299
+ const [data, setData] = (0, import_react11.useState)();
1300
+ const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
1301
+ const [pdfLoading, setPdfLoading] = (0, import_react11.useState)(false);
1302
+ const [error, setError] = (0, import_react11.useState)(null);
1303
+ const get = async ({ url, v = 1, params, delay }) => {
1304
+ setIsLoading(true);
1305
+ try {
1306
+ if (delay) await new Promise((r) => setTimeout(r, delay));
1307
+ const response = await api.get(`/v${v}${url}`, { params });
1308
+ setData(response.data);
1309
+ setError(null);
1310
+ return response.data;
1311
+ } catch (err) {
1312
+ const msg = err.response?.data?.message || err.message || "Something went wrong";
1313
+ setError(msg);
1314
+ setData(null);
1315
+ throw new Error(msg);
1316
+ } finally {
1317
+ setIsLoading(false);
1318
+ }
1319
+ };
1320
+ const post = async ({
1321
+ url,
1322
+ v = 1,
1323
+ body,
1324
+ form,
1325
+ multipart = false
1326
+ }) => {
1327
+ setIsLoading(true);
1328
+ try {
1329
+ let response;
1330
+ if (multipart) {
1331
+ const formData = new FormData();
1332
+ if (body) {
1333
+ Object.keys(body).forEach((key) => {
1334
+ if (key === "files") {
1335
+ const files = body[key];
1336
+ if (Array.isArray(files)) {
1337
+ files.forEach((file) => formData.append(key, file));
1338
+ } else {
1339
+ formData.append(key, files);
1340
+ }
1341
+ } else if (Array.isArray(body[key]) || typeof body[key] === "object") {
1342
+ formData.append(key, JSON.stringify(body[key]));
1343
+ } else {
1344
+ formData.append(key, body[key]);
1345
+ }
1346
+ });
1347
+ }
1348
+ response = await api.post(`/v${v}${url}`, formData, {
1349
+ headers: { "Content-Type": "multipart/form-data" }
1350
+ });
1351
+ } else {
1352
+ response = await api.post(`/v${v}${url}`, body);
1353
+ }
1354
+ setData(response.data);
1355
+ return response.data;
1356
+ } catch (err) {
1357
+ const msg = err.response?.data?.message || err.message || "Something went wrong";
1358
+ setError(msg);
1359
+ if (form) {
1360
+ if (msg !== "zodError") {
1361
+ form.setError("root", { message: msg });
1362
+ } else {
1363
+ const errors = err?.response?.data?.errors || [];
1364
+ errors.forEach((e) => {
1365
+ form.setError(e.field, { message: e.message });
1366
+ });
1367
+ }
1368
+ }
1369
+ throw new Error(msg);
1370
+ } finally {
1371
+ setIsLoading(false);
1372
+ }
1373
+ };
1374
+ const put = async ({ url, v = 1, body }) => {
1375
+ setIsLoading(true);
1376
+ try {
1377
+ const response = await api.put(`/v${v}${url}`, body);
1378
+ setData(response.data);
1379
+ return response.data;
1380
+ } catch (err) {
1381
+ const msg = err.response?.data?.message || err.message || "Something went wrong";
1382
+ setError(msg);
1383
+ throw new Error(msg);
1384
+ } finally {
1385
+ setIsLoading(false);
1386
+ }
1387
+ };
1388
+ const remove = async ({ url, v = 1, params }) => {
1389
+ setIsLoading(true);
1390
+ try {
1391
+ const response = await api.delete(`/v${v}${url}`, { params });
1392
+ setData(response.data);
1393
+ setError(null);
1394
+ return response.data;
1395
+ } catch (err) {
1396
+ const msg = err.response?.data?.message || err.message || "Something went wrong";
1397
+ setError(msg);
1398
+ setData(null);
1399
+ throw new Error(msg);
1400
+ } finally {
1401
+ setIsLoading(false);
1402
+ }
1403
+ };
1404
+ const fetchPdf = async ({
1405
+ url,
1406
+ v = 1,
1407
+ method,
1408
+ body
1409
+ }) => {
1410
+ setPdfLoading(true);
1411
+ try {
1412
+ const response = await api.request({
1413
+ url: `/v${v}${url}`,
1414
+ method,
1415
+ data: body,
1416
+ responseType: "blob"
1417
+ });
1418
+ if (!response.data || response.data.size === 0) {
1419
+ return { ok: false, message: "Received empty PDF file", errors: [] };
1420
+ }
1421
+ setError(null);
1422
+ const pdfObjectUrl = URL.createObjectURL(response.data);
1423
+ return { ok: true, data: pdfObjectUrl };
1424
+ } catch (err) {
1425
+ return {
1426
+ ok: false,
1427
+ message: err.response?.data?.message || err.message || "Server error, something went wrong"
1428
+ };
1429
+ } finally {
1430
+ setPdfLoading(false);
1431
+ }
1432
+ };
1433
+ return {
1434
+ data,
1435
+ error,
1436
+ isLoading,
1437
+ pdfLoading,
1438
+ get,
1439
+ post,
1440
+ put,
1441
+ remove,
1442
+ fetchPdf
1443
+ };
1444
+ };
1445
+ var useApis_default = useApi;
1446
+
1447
+ // src/components/Fields/searchApi.tsx
1448
+ var import_react_hook_form4 = require("react-hook-form");
1449
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1450
+ var SearchApiContent = ({
1451
+ label,
1452
+ apiUrl,
1453
+ placeholder = "Search...",
1454
+ currentValue,
1455
+ onChangeHandler,
1456
+ queryKey = "search",
1457
+ labelKey = "name",
1458
+ valueKey = "_id",
1459
+ error,
1460
+ containerClassName = "",
1461
+ className = "",
1462
+ disabled,
1463
+ name,
1464
+ obj,
1465
+ form,
1466
+ filter = [],
1467
+ required,
1468
+ v = 2,
1469
+ fieldInternalProps,
1470
+ ...props
1471
+ }) => {
1472
+ const [searchTerm, setSearchTerm] = (0, import_react12.useState)("");
1473
+ const { theme } = useWarqadConfig();
1474
+ const primaryColor = theme?.primaryColor;
1475
+ const [options, setOptions] = (0, import_react12.useState)([]);
1476
+ const [isOpen, setIsOpen] = (0, import_react12.useState)(false);
1477
+ const [isFocused, setIsFocused] = (0, import_react12.useState)(false);
1478
+ const [activeIndex, setActiveIndex] = (0, import_react12.useState)(-1);
1479
+ const [selectedObject, setSelectedObject] = (0, import_react12.useState)(void 0);
1480
+ const [hasAttemptedHydration, setHasAttemptedHydration] = (0, import_react12.useState)(false);
1481
+ const containerRef = (0, import_react12.useRef)(null);
1482
+ const inputRef = (0, import_react12.useRef)(null);
1483
+ const prevApiUrlRef = (0, import_react12.useRef)(apiUrl);
1484
+ const setInputRef = (element) => {
1485
+ inputRef.current = element;
1486
+ if (fieldInternalProps?.ref) {
1487
+ if (typeof fieldInternalProps.ref === "function") {
1488
+ fieldInternalProps.ref(element);
1489
+ } else {
1490
+ fieldInternalProps.ref.current = element;
1491
+ }
1492
+ }
1493
+ };
1494
+ const { get, isLoading, error: errorMessage } = useApis_default();
1495
+ const fetchOptions = async (query) => {
1496
+ try {
1497
+ const params = {};
1498
+ if (query) params[queryKey] = query;
1499
+ const response = await get({
1500
+ url: apiUrl,
1501
+ params,
1502
+ v
1503
+ });
1504
+ if (Array.isArray(response)) {
1505
+ setOptions(response);
1506
+ } else if (response?.data && Array.isArray(response.data)) {
1507
+ setOptions(response.data);
1508
+ } else if (response?.items && Array.isArray(response.items)) {
1509
+ setOptions(response.items);
1510
+ } else {
1511
+ setOptions([]);
1512
+ }
1513
+ } catch (err) {
1514
+ console.error("Failed to fetch options:", err);
1515
+ if (form && name) {
1516
+ form.setError(name, {
1517
+ type: "manual",
1518
+ message: err.message || "Failed to fetch options"
1519
+ });
1520
+ }
1521
+ setOptions([]);
1522
+ }
1523
+ };
1524
+ (0, import_react12.useEffect)(() => {
1525
+ const timer = setTimeout(() => {
1526
+ if (isOpen) {
1527
+ fetchOptions(searchTerm);
1528
+ }
1529
+ }, 300);
1530
+ return () => clearTimeout(timer);
1531
+ }, [searchTerm, apiUrl, isOpen]);
1532
+ (0, import_react12.useEffect)(() => {
1533
+ if (isOpen && options.length === 0) {
1534
+ fetchOptions("");
1535
+ }
1536
+ }, [isOpen]);
1537
+ (0, import_react12.useEffect)(() => {
1538
+ if (currentValue && !selectedObject) {
1539
+ setHasAttemptedHydration(false);
1540
+ fetchOptions(currentValue).finally(() => {
1541
+ setHasAttemptedHydration(true);
1542
+ });
1543
+ } else if (!currentValue) {
1544
+ setHasAttemptedHydration(true);
1545
+ if (selectedObject) setSelectedObject(void 0);
1546
+ }
1547
+ }, [currentValue, selectedObject]);
1548
+ const getOptionValue = (option) => {
1549
+ if (valueKey === "_id" && option._id === void 0 && option.id !== void 0) {
1550
+ return option.id;
1551
+ }
1552
+ return option[valueKey];
1553
+ };
1554
+ (0, import_react12.useEffect)(() => {
1555
+ if (currentValue && !selectedObject && options.length > 0) {
1556
+ const found = options.find((o) => getOptionValue(o) === currentValue);
1557
+ if (found) {
1558
+ setSelectedObject(found);
1559
+ if (form && obj) {
1560
+ form.setValue(obj, found);
1561
+ }
1562
+ }
1563
+ }
1564
+ }, [currentValue, options, selectedObject, form, obj]);
1565
+ (0, import_react12.useEffect)(() => {
1566
+ if (prevApiUrlRef.current !== apiUrl) {
1567
+ prevApiUrlRef.current = apiUrl;
1568
+ setSearchTerm("");
1569
+ setOptions([]);
1570
+ setSelectedObject(void 0);
1571
+ if (form) {
1572
+ if (name) {
1573
+ form.setValue(name, void 0, {
1574
+ shouldValidate: true,
1575
+ shouldDirty: true
1576
+ });
1577
+ }
1578
+ if (obj) {
1579
+ form.setValue(obj, void 0, {
1580
+ shouldValidate: true,
1581
+ shouldDirty: true
1582
+ });
1583
+ }
1584
+ } else {
1585
+ onChangeHandler(void 0);
1586
+ }
1587
+ fetchOptions("");
1588
+ }
1589
+ }, [apiUrl, form, name, obj, onChangeHandler]);
1590
+ (0, import_react12.useEffect)(() => {
1591
+ const handleClickOutside = (event) => {
1592
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
1593
+ setIsOpen(false);
1594
+ setIsFocused(false);
1595
+ setSearchTerm("");
1596
+ fieldInternalProps?.onBlur?.();
1597
+ }
1598
+ };
1599
+ document.addEventListener("mousedown", handleClickOutside);
1600
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1601
+ }, [fieldInternalProps]);
1602
+ const getDisplayValue = () => {
1603
+ if (selectedObject) return selectedObject[labelKey];
1604
+ if (options.length > 0 && currentValue) {
1605
+ const found = options.find((o) => getOptionValue(o) === currentValue);
1606
+ if (found) return found[labelKey];
1607
+ }
1608
+ if (isLoading || currentValue && !hasAttemptedHydration)
1609
+ return "Loading...";
1610
+ return currentValue || "";
1611
+ };
1612
+ const handleSelect = (option) => {
1613
+ const value = getOptionValue(option);
1614
+ setSelectedObject(option);
1615
+ onChangeHandler(value);
1616
+ if (form) {
1617
+ if (obj) form.setValue(obj, option);
1618
+ if (name) form.clearErrors(name);
1619
+ }
1620
+ setIsOpen(false);
1621
+ setSearchTerm("");
1622
+ setActiveIndex(-1);
1623
+ fieldInternalProps?.onBlur?.();
1624
+ };
1625
+ const handleKeyDown = (e) => {
1626
+ if (!isOpen) {
1627
+ if (e.key === "ArrowDown" || e.key === "Enter") setIsOpen(true);
1628
+ return;
1629
+ }
1630
+ switch (e.key) {
1631
+ case "ArrowDown":
1632
+ e.preventDefault();
1633
+ setActiveIndex((prev) => prev < options.length - 1 ? prev + 1 : prev);
1634
+ break;
1635
+ case "ArrowUp":
1636
+ e.preventDefault();
1637
+ setActiveIndex((prev) => prev > 0 ? prev - 1 : prev);
1638
+ break;
1639
+ case "Enter":
1640
+ e.preventDefault();
1641
+ if (activeIndex >= 0 && activeIndex < options.length)
1642
+ handleSelect(options[activeIndex]);
1643
+ break;
1644
+ case "Escape":
1645
+ setIsOpen(false);
1646
+ break;
1647
+ }
1648
+ };
1649
+ const clearSelection = (e) => {
1650
+ e.stopPropagation();
1651
+ if (form) {
1652
+ if (name)
1653
+ form.setValue(name, void 0, {
1654
+ shouldValidate: true,
1655
+ shouldDirty: true
1656
+ });
1657
+ if (obj)
1658
+ form.setValue(obj, void 0, {
1659
+ shouldValidate: true,
1660
+ shouldDirty: true
1661
+ });
1662
+ } else {
1663
+ onChangeHandler(void 0);
1664
+ }
1665
+ setSearchTerm("");
1666
+ };
1667
+ const filteredOptions = options.filter(
1668
+ (option) => !filter.includes(getOptionValue(option))
1669
+ );
1670
+ (0, import_react12.useEffect)(() => {
1671
+ if (form && name && !form.watch(name)) {
1672
+ form.setValue(name, void 0);
1673
+ if (obj) form.setValue(obj, void 0);
1674
+ }
1675
+ }, [form, name, obj]);
1676
+ let message = error;
1677
+ if (form && name) {
1678
+ const {
1679
+ formState: { errors }
1680
+ } = form;
1681
+ const nameParts = name.split(".");
1682
+ let currentError = errors;
1683
+ for (const part of nameParts) {
1684
+ currentError = currentError?.[part];
1685
+ }
1686
+ message = currentError?.message || message;
1687
+ }
1688
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: containerRef, className: `space-y-2 group ${containerClassName}`, children: [
1689
+ label && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1690
+ "label",
1691
+ {
1692
+ className: `block text-xs font-medium transition-colors duration-200`,
1693
+ style: { color: isFocused || isOpen ? primaryColor : void 0 },
1694
+ children: [
1695
+ label,
1696
+ required && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
1697
+ ]
1698
+ }
1699
+ ),
1700
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative", children: [
1701
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1702
+ "div",
1703
+ {
1704
+ className: `flex items-center w-full h-8 rounded-lg border bg-gray-50 dark:bg-zinc-900/50 text-gray-900 dark:text-white transition-all duration-200 cursor-text ${isFocused || isOpen ? "ring-2 bg-white dark:bg-zinc-900" : "border-gray-200 dark:border-zinc-800"} ${className}`,
1705
+ style: {
1706
+ borderColor: isFocused || isOpen ? primaryColor : void 0,
1707
+ boxShadow: isFocused || isOpen ? `${primaryColor}33 0px 0px 0px 2px` : void 0
1708
+ },
1709
+ onClick: () => {
1710
+ if (disabled) return;
1711
+ inputRef.current?.focus();
1712
+ setIsOpen(true);
1713
+ },
1714
+ children: [
1715
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "pl-3 text-gray-400", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Search, { className: "h-4 w-4" }) }),
1716
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1 relative", children: [
1717
+ !isOpen && currentValue && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "absolute inset-0 flex items-center px-3 truncate select-none", children: getDisplayValue() }),
1718
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1719
+ "input",
1720
+ {
1721
+ ref: setInputRef,
1722
+ type: "text",
1723
+ className: `block w-full bg-transparent border-none focus:ring-0 h-8 py-0 pr-8 placeholder-gray-400 focus:outline-none text-sm ${!isOpen && currentValue ? "opacity-0" : "opacity-100"}`,
1724
+ placeholder: !currentValue ? placeholder : "",
1725
+ value: searchTerm,
1726
+ onChange: (e) => setSearchTerm(e.target.value),
1727
+ onFocus: () => {
1728
+ setIsFocused(true);
1729
+ setIsOpen(true);
1730
+ },
1731
+ onKeyDown: handleKeyDown,
1732
+ disabled,
1733
+ ...props
1734
+ }
1735
+ )
1736
+ ] }),
1737
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "pr-3 flex items-center gap-1", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Loader2, { className: "h-4 w-4 animate-spin text-blue-500" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
1738
+ currentValue && !disabled && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1739
+ "button",
1740
+ {
1741
+ onClick: clearSelection,
1742
+ type: "button",
1743
+ className: "p-0.5 hover:bg-gray-200 dark:hover:bg-zinc-700 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-300",
1744
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { className: "h-3 w-3" })
1745
+ }
1746
+ ),
1747
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1748
+ import_lucide_react8.ChevronDown,
1749
+ {
1750
+ className: `h-4 w-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
1751
+ }
1752
+ )
1753
+ ] }) })
1754
+ ]
1755
+ }
1756
+ ),
1757
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "absolute z-50 w-full mt-1 bg-white dark:bg-zinc-900 rounded-xl border border-gray-200 dark:border-zinc-800 shadow-lg max-h-60 overflow-y-auto overflow-x-hidden", children: isLoading && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "p-4 text-center text-sm text-gray-500", children: [
1758
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Loader2, { className: "h-5 w-5 animate-spin mx-auto mb-2" }),
1759
+ "Loading options..."
1760
+ ] }) : filteredOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "py-1", children: filteredOptions.map((option, index) => {
1761
+ const optValue = getOptionValue(option);
1762
+ const isSelected = currentValue === optValue;
1763
+ const isHighlighted = index === activeIndex;
1764
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1765
+ "button",
1766
+ {
1767
+ type: "button",
1768
+ className: `w-full text-left px-3 py-2 text-sm flex items-center justify-between transition-colors ${isSelected ? "font-medium" : isHighlighted ? "bg-gray-100 dark:bg-zinc-800 text-gray-900 dark:text-gray-100" : "text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-zinc-800"}`,
1769
+ style: {
1770
+ backgroundColor: isSelected ? `${primaryColor}1A` : void 0,
1771
+ color: isSelected ? primaryColor : void 0
1772
+ },
1773
+ onClick: () => handleSelect(option),
1774
+ onMouseEnter: () => setActiveIndex(index),
1775
+ children: [
1776
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: option[labelKey] }),
1777
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1778
+ import_lucide_react8.Check,
1779
+ {
1780
+ className: "h-4 w-4",
1781
+ style: { color: primaryColor }
1782
+ }
1783
+ )
1784
+ ]
1785
+ },
1786
+ optValue || index
1787
+ );
1788
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "p-4 text-center text-sm text-gray-500", children: errorMessage || (searchTerm ? `No results for "${searchTerm}"` : "No options available") }) })
1789
+ ] }),
1790
+ message && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
1791
+ ] });
1792
+ };
1793
+ var SearchApi = (0, import_react12.forwardRef)(
1794
+ (props, _) => {
1795
+ const { form, name, onChange, value } = props;
1796
+ if (form && name) {
1797
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1798
+ import_react_hook_form4.Controller,
1799
+ {
1800
+ name,
1801
+ control: form.control,
1802
+ render: ({
1803
+ field: { onChange: formOnChange, value: formValue, ref, onBlur }
1804
+ }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1805
+ SearchApiContent,
1806
+ {
1807
+ ...props,
1808
+ currentValue: formValue,
1809
+ onChangeHandler: formOnChange,
1810
+ fieldInternalProps: { ref, onBlur }
1811
+ }
1812
+ )
1813
+ }
1814
+ );
1815
+ }
1816
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1817
+ SearchApiContent,
1818
+ {
1819
+ ...props,
1820
+ currentValue: value,
1821
+ onChangeHandler: onChange || (() => {
1822
+ })
1823
+ }
1824
+ );
1825
+ }
1826
+ );
1827
+ SearchApi.displayName = "SearchApi";
1828
+
1829
+ // src/components/Fields/date.tsx
1830
+ var import_react13 = require("react");
1831
+ var import_antd = require("antd");
1832
+ var import_react_hook_form5 = require("react-hook-form");
1833
+ var import_dayjs = __toESM(require("dayjs"));
1834
+ var import_customParseFormat = __toESM(require("dayjs/plugin/customParseFormat"));
1835
+ var import_lucide_react9 = require("lucide-react");
1836
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1837
+ import_dayjs.default.extend(import_customParseFormat.default);
1838
+ var DateInput = (0, import_react13.forwardRef)(
1839
+ ({
1840
+ label,
1841
+ error,
1842
+ containerClassName = "",
1843
+ name,
1844
+ form,
1845
+ className = "",
1846
+ value,
1847
+ onBlur = () => {
1848
+ },
1849
+ onChange = () => {
1850
+ },
1851
+ ...props
1852
+ }, ref) => {
1853
+ const { theme } = useWarqadConfig();
1854
+ const primaryColor = theme?.primaryColor;
1855
+ const [isFocused, setIsFocused] = (0, import_react13.useState)(false);
1856
+ let message = error;
1857
+ if (form && name) {
1858
+ const {
1859
+ formState: { errors }
1860
+ } = form;
1861
+ const errorObj = name.split(".").reduce((acc, current) => acc?.[current], errors);
1862
+ message = errorObj?.message;
1863
+ }
1864
+ const inputStyles = `w-full px-3 py-0 rounded-lg! border! shadow-none transition-all! duration-200! outline-none!
1865
+ bg-gray-50! dark:bg-zinc-900!
1866
+ text-gray-900! dark:text-zinc-100!
1867
+ hover:bg-gray-50! dark:hover:bg-zinc-900!
1868
+ ${message ? "border-red-500 hover:border-red-500 [&.ant-picker-focused]:border-red-500 [&.ant-picker-focused]:ring-red-500/20" : "border-gray-200 dark:border-zinc-700 hover:border-gray-200 dark:hover:border-zinc-700 [&.ant-picker-focused]:ring-2"}
1869
+ [&.ant-picker-focused]:bg-white dark:[&.ant-picker-focused]:bg-zinc-900
1870
+ ${className}`;
1871
+ const renderDatePicker = (val, changeHandler, blurHandler, refProps) => {
1872
+ const dateValue = val && typeof val === "string" ? (0, import_dayjs.default)(val, "DD/MM/YYYY", true) : import_dayjs.default.isDayjs(val) ? val : null;
1873
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1874
+ import_antd.DatePicker,
1875
+ {
1876
+ ref: refProps,
1877
+ format: "DD/MM/YYYY",
1878
+ value: dateValue && dateValue.isValid() ? dateValue : null,
1879
+ onChange: (date) => {
1880
+ if (date && import_dayjs.default.isDayjs(date)) {
1881
+ changeHandler?.(date.format("DD/MM/YYYY"));
1882
+ } else {
1883
+ changeHandler?.("");
1884
+ }
1885
+ },
1886
+ onFocus: () => setIsFocused(true),
1887
+ onBlur: () => {
1888
+ setIsFocused(false);
1889
+ blurHandler?.();
1890
+ },
1891
+ className: `${inputStyles} [&>input]:text-gray-900! [&>input]:dark:text-zinc-100! [&>input]:text-base rounded-md`,
1892
+ placeholder: "DD/MM/YYYY",
1893
+ needConfirm: false,
1894
+ style: {
1895
+ height: "32px",
1896
+ borderColor: isFocused && !message ? primaryColor : void 0,
1897
+ boxShadow: isFocused && !message ? `${primaryColor}33 0px 0px 0px 2px` : void 0
1898
+ },
1899
+ popupClassName: "z-50",
1900
+ suffixIcon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1901
+ import_lucide_react9.Calendar,
1902
+ {
1903
+ className: "h-5 w-5 text-gray-400",
1904
+ style: { color: isFocused ? primaryColor : void 0 }
1905
+ }
1906
+ ),
1907
+ allowClear: true,
1908
+ ...props
1909
+ }
1910
+ );
1911
+ };
1912
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: `space-y-2 group ${containerClassName}`, children: [
1913
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1914
+ "label",
1915
+ {
1916
+ className: "block text-xs font-medium transition-colors duration-200",
1917
+ style: {
1918
+ color: message ? "#ef4444" : isFocused ? primaryColor : void 0
1919
+ },
1920
+ children: label
1921
+ }
1922
+ ),
1923
+ form && name ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1924
+ import_react_hook_form5.Controller,
1925
+ {
1926
+ control: form.control,
1927
+ name,
1928
+ render: ({ field }) => renderDatePicker(
1929
+ field.value,
1930
+ field.onChange,
1931
+ field.onBlur,
1932
+ field.ref
1933
+ )
1934
+ }
1935
+ ) : renderDatePicker(value, onChange, onBlur, ref),
1936
+ message && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
1937
+ ] });
1938
+ }
1939
+ );
1940
+
1941
+ // src/components/Fields/index.tsx
1942
+ var Fields = {
1943
+ Input,
1944
+ PhoneInput,
1945
+ Select,
1946
+ Textarea,
1947
+ SearchApi,
1948
+ DateInput
1949
+ };
1950
+ var Fields_default = Fields;
1951
+
1952
+ // src/components/tables/DataTable.tsx
1953
+ var import_react14 = require("react");
1954
+ var import_react_table = require("@tanstack/react-table");
1955
+ var import_lucide_react10 = require("lucide-react");
1956
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1957
+ function DataTable({
1958
+ columns,
1959
+ data,
1960
+ isLoading = false,
1961
+ pageRows,
1962
+ searchPlaceholder = "Search all columns...",
1963
+ className = "",
1964
+ onChange
1965
+ }) {
1966
+ const { theme } = useWarqadConfig();
1967
+ const primaryColor = theme?.primaryColor;
1968
+ const [sorting, setSorting] = (0, import_react14.useState)([]);
1969
+ const [columnFilters, setColumnFilters] = (0, import_react14.useState)([]);
1970
+ const [columnVisibility, setColumnVisibility] = (0, import_react14.useState)({});
1971
+ const [rowSelection, setRowSelection] = (0, import_react14.useState)({});
1972
+ const [globalFilter, setGlobalFilter] = (0, import_react14.useState)("");
1973
+ const table = (0, import_react_table.useReactTable)({
1974
+ data,
1975
+ columns,
1976
+ onSortingChange: setSorting,
1977
+ onColumnFiltersChange: setColumnFilters,
1978
+ getCoreRowModel: (0, import_react_table.getCoreRowModel)(),
1979
+ getPaginationRowModel: pageRows ? (0, import_react_table.getPaginationRowModel)() : void 0,
1980
+ getSortedRowModel: (0, import_react_table.getSortedRowModel)(),
1981
+ getFilteredRowModel: (0, import_react_table.getFilteredRowModel)(),
1982
+ onColumnVisibilityChange: setColumnVisibility,
1983
+ onRowSelectionChange: setRowSelection,
1984
+ onGlobalFilterChange: setGlobalFilter,
1985
+ globalFilterFn: "includesString",
1986
+ state: {
1987
+ sorting,
1988
+ columnFilters,
1989
+ columnVisibility,
1990
+ rowSelection,
1991
+ globalFilter,
1992
+ ...pageRows ? { pagination: { pageSize: pageRows, pageIndex: 0 } } : {}
1993
+ },
1994
+ manualPagination: false
1995
+ });
1996
+ (0, import_react14.useEffect)(() => {
1997
+ if (onChange) {
1998
+ onChange({
1999
+ pagination: {
2000
+ pageIndex: table.getState().pagination.pageIndex,
2001
+ pageSize: table.getState().pagination.pageSize,
2002
+ pageCount: table.getPageCount()
2003
+ },
2004
+ sorting,
2005
+ columnFilters,
2006
+ globalFilter,
2007
+ selectedRows: table.getSelectedRowModel().rows.map((row) => row.original),
2008
+ filteredData: table.getFilteredRowModel().rows.map((row) => row.original)
2009
+ });
2010
+ }
2011
+ }, [
2012
+ sorting,
2013
+ columnFilters,
2014
+ globalFilter,
2015
+ rowSelection,
2016
+ table,
2017
+ onChange,
2018
+ table.getState().pagination.pageIndex,
2019
+ table.getState().pagination.pageSize
2020
+ ]);
2021
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `space-y-4 w-full ${className}`, children: [
2022
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
2023
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 max-w-sm", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2024
+ Fields_default.Input,
2025
+ {
2026
+ label: "Search",
2027
+ placeholder: searchPlaceholder,
2028
+ value: globalFilter,
2029
+ onChange: (e) => setGlobalFilter(e.target.value),
2030
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Search, { size: 16 }),
2031
+ className: "!h-9"
2032
+ }
2033
+ ) }),
2034
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "relative group", children: [
2035
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { className: "flex items-center gap-2 px-3 h-9 rounded-lg border border-gray-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 text-sm font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors", children: [
2036
+ "Columns",
2037
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.ChevronDown, { size: 14, className: "text-gray-400" })
2038
+ ] }),
2039
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute right-0 top-full mt-2 w-48 py-1 bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-800 rounded-lg shadow-xl opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all z-50", children: table.getAllColumns().filter((column) => column.getCanHide()).map((column) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
2040
+ "label",
2041
+ {
2042
+ className: "flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-zinc-800 cursor-pointer capitalize",
2043
+ children: [
2044
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2045
+ "input",
2046
+ {
2047
+ type: "checkbox",
2048
+ checked: column.getIsVisible(),
2049
+ onChange: (e) => column.toggleVisibility(!!e.target.checked),
2050
+ className: "rounded border-gray-300 text-blue-600 focus:ring-blue-500",
2051
+ style: { accentColor: primaryColor }
2052
+ }
2053
+ ),
2054
+ column.id
2055
+ ]
2056
+ },
2057
+ column.id
2058
+ )) })
2059
+ ] }) })
2060
+ ] }),
2061
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "rounded-lg border border-gray-200 dark:border-zinc-800 bg-white dark:bg-zinc-950 overflow-hidden relative", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("table", { className: "w-full text-left border-collapse", children: [
2062
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("thead", { className: "bg-gray-50/50 dark:bg-zinc-900/50 border-b border-gray-200 dark:border-zinc-800", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2063
+ "th",
2064
+ {
2065
+ className: "px-4 py-3 text-[13px] font-semibold text-gray-900 dark:text-zinc-100 text-left",
2066
+ children: header.isPlaceholder ? null : (0, import_react_table.flexRender)(
2067
+ header.column.columnDef.header,
2068
+ header.getContext()
2069
+ )
2070
+ },
2071
+ header.id
2072
+ )) }, headerGroup.id)) }),
2073
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tbody", { className: "divide-y divide-gray-200 dark:divide-zinc-800", children: isLoading ? Array.from({ length: pageRows || 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2074
+ "tr",
2075
+ {
2076
+ className: "border-b border-gray-100 dark:border-zinc-800/50",
2077
+ children: columns.map((_2, j) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("td", { className: "px-4 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "h-4 bg-gray-100 dark:bg-zinc-800 rounded animate-pulse w-full" }) }, `skeleton-cell-${j}`))
2078
+ },
2079
+ `skeleton-${i}`
2080
+ )) : table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2081
+ "tr",
2082
+ {
2083
+ className: "hover:bg-gray-50/50 dark:hover:bg-zinc-900/50 transition-colors",
2084
+ "data-state": row.getIsSelected() && "selected",
2085
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2086
+ "td",
2087
+ {
2088
+ className: "px-4 py-3 text-sm text-gray-700 dark:text-gray-200",
2089
+ children: (0, import_react_table.flexRender)(
2090
+ cell.column.columnDef.cell,
2091
+ cell.getContext()
2092
+ )
2093
+ },
2094
+ cell.id
2095
+ ))
2096
+ },
2097
+ row.id
2098
+ )) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2099
+ "td",
2100
+ {
2101
+ colSpan: columns.length,
2102
+ className: "h-32 text-center text-sm text-gray-500",
2103
+ children: "No results found."
2104
+ }
2105
+ ) }) })
2106
+ ] }) }) }),
2107
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between px-2", children: [
2108
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 text-xs text-gray-500", children: [
2109
+ table.getFilteredSelectedRowModel().rows.length,
2110
+ " of",
2111
+ " ",
2112
+ table.getFilteredRowModel().rows.length,
2113
+ " row(s) selected."
2114
+ ] }),
2115
+ pageRows && table.getPageCount() > 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
2116
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2117
+ "button",
2118
+ {
2119
+ onClick: () => table.previousPage(),
2120
+ disabled: !table.getCanPreviousPage(),
2121
+ className: "p-1 px-3 rounded-md border border-gray-200 dark:border-zinc-800 text-sm disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors",
2122
+ children: "Previous"
2123
+ }
2124
+ ),
2125
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2126
+ "button",
2127
+ {
2128
+ onClick: () => table.nextPage(),
2129
+ disabled: !table.getCanNextPage(),
2130
+ className: "p-1 px-3 rounded-md border border-gray-200 dark:border-zinc-800 text-sm disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50 dark:hover:bg-zinc-800 transition-colors",
2131
+ children: "Next"
2132
+ }
2133
+ )
2134
+ ] })
2135
+ ] })
2136
+ ] });
2137
+ }
2138
+
2139
+ // src/utils/pdf.ts
2140
+ var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
2141
+ var import_jspdf = require("jspdf");
2142
+ var generatePdf = async (elementId, options = {}) => {
2143
+ const {
2144
+ orientation = "landscape",
2145
+ unit = "mm",
2146
+ format = "a4",
2147
+ filename = "export.pdf",
2148
+ margin = 10,
2149
+ windowWidth = 1200,
2150
+ scale = 1,
2151
+ showPageNumbers = true
2152
+ } = options;
2153
+ const element = document.getElementById(elementId);
2154
+ if (!element) {
2155
+ console.error(
2156
+ `PDF generation failed: Element with ID "${elementId}" not found.`
2157
+ );
2158
+ return;
2159
+ }
2160
+ try {
2161
+ const pdf = new import_jspdf.jsPDF({
2162
+ orientation,
2163
+ unit,
2164
+ format,
2165
+ compress: true
2166
+ });
2167
+ const pageWidth = pdf.internal.pageSize.getWidth();
2168
+ const pageHeight = pdf.internal.pageSize.getHeight();
2169
+ window.html2canvas = import_html2canvas_pro.default;
2170
+ await pdf.html(element, {
2171
+ callback: function(doc) {
2172
+ if (showPageNumbers) {
2173
+ const pageCount = doc.internal.getNumberOfPages();
2174
+ for (let i = 1; i <= pageCount; i++) {
2175
+ doc.setPage(i);
2176
+ doc.setFontSize(8);
2177
+ doc.setTextColor(150);
2178
+ const text = `Page ${i} of ${pageCount}`;
2179
+ const textWidth = doc.getStringUnitWidth(text) * 8 / doc.internal.scaleFactor;
2180
+ doc.text(text, (pageWidth - textWidth) / 2, pageHeight - 5);
2181
+ }
2182
+ }
2183
+ doc.save(filename);
2184
+ const pdfBlob = doc.output("blob");
2185
+ const url = URL.createObjectURL(pdfBlob);
2186
+ window.open(url, "_blank");
2187
+ },
2188
+ x: margin,
2189
+ y: margin,
2190
+ width: pageWidth - margin * 2,
2191
+ windowWidth,
2192
+ html2canvas: {
2193
+ useCORS: true,
2194
+ scale: Math.max(scale, 2),
2195
+ // Ensure scale is at least 2 for text clarity
2196
+ logging: false,
2197
+ onclone: (clonedDoc) => {
2198
+ const elements = clonedDoc.getElementsByTagName("*");
2199
+ const tempCanvas = clonedDoc.createElement("canvas");
2200
+ tempCanvas.width = 1;
2201
+ tempCanvas.height = 1;
2202
+ const ctx = tempCanvas.getContext("2d");
2203
+ const target = clonedDoc.getElementById(elementId);
2204
+ if (target) {
2205
+ target.style.width = `${windowWidth}px`;
2206
+ target.style.maxWidth = "none";
2207
+ }
2208
+ const toRgb = (color) => {
2209
+ if (!color || !color.includes("oklch") && !color.includes("oklab"))
2210
+ return color;
2211
+ if (!ctx) return "rgb(0,0,0)";
2212
+ try {
2213
+ ctx.fillStyle = color;
2214
+ const result = ctx.fillStyle;
2215
+ return result.includes("ok") ? "rgb(0,0,0)" : result;
2216
+ } catch (e) {
2217
+ return "rgb(0,0,0)";
2218
+ }
2219
+ };
2220
+ for (let i = 0; i < elements.length; i++) {
2221
+ const el = elements[i];
2222
+ const style = window.getComputedStyle(elements[i]);
2223
+ const colorProps = [
2224
+ "color",
2225
+ "backgroundColor",
2226
+ "borderColor",
2227
+ "borderTopColor",
2228
+ "borderBottomColor",
2229
+ "borderLeftColor",
2230
+ "borderRightColor",
2231
+ "fill",
2232
+ "stroke",
2233
+ "outlineColor",
2234
+ "stopColor",
2235
+ "floodColor",
2236
+ "lightingColor"
2237
+ ];
2238
+ colorProps.forEach((prop) => {
2239
+ const val = style[prop];
2240
+ if (val && (val.includes("oklch") || val.includes("oklab"))) {
2241
+ el.style[prop] = toRgb(val);
2242
+ }
2243
+ });
2244
+ }
2245
+ const styleTags = clonedDoc.getElementsByTagName("style");
2246
+ for (let i = 0; i < styleTags.length; i++) {
2247
+ let cssText = styleTags[i].innerHTML;
2248
+ if (cssText.includes("oklch") || cssText.includes("oklab")) {
2249
+ cssText = cssText.replace(/oklch\([^)]+\)/g, "rgb(0,0,0)");
2250
+ cssText = cssText.replace(/oklab\([^)]+\)/g, "rgb(0,0,0)");
2251
+ styleTags[i].innerHTML = cssText;
2252
+ }
2253
+ }
2254
+ }
2255
+ },
2256
+ autoPaging: "text"
2257
+ });
2258
+ } catch (error) {
2259
+ console.error("PDF generation failed:", error);
2260
+ throw error;
2261
+ }
2262
+ };
2263
+ // Annotate the CommonJS export names for ESM import in node:
2264
+ 0 && (module.exports = {
2265
+ Button,
2266
+ Card,
2267
+ CardContent,
2268
+ CardDescription,
2269
+ CardFooter,
2270
+ CardHeader,
2271
+ CardTitle,
2272
+ ClassicSpin,
2273
+ CodeBlock,
2274
+ DashboardLayout,
2275
+ DataTable,
2276
+ DateInput,
2277
+ Fields,
2278
+ Input,
2279
+ LoadingBox,
2280
+ LoadingSpin,
2281
+ Modal,
2282
+ OverlaySpin,
2283
+ PageHeader,
2284
+ PhoneInput,
2285
+ SearchApi,
2286
+ Select,
2287
+ Textarea,
2288
+ ThemeProvider,
2289
+ ThemeToggle,
2290
+ WarqadProvider,
2291
+ generatePdf,
2292
+ useApi,
2293
+ useModal,
2294
+ useTheme,
2295
+ useWarqadConfig
2296
+ });