injast-core 1.0.78

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 (127) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +127 -0
  3. package/dist/components/index.js +3187 -0
  4. package/dist/constants/index.js +138 -0
  5. package/dist/context/index.js +308 -0
  6. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Black.woff +0 -0
  7. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Bold.woff +0 -0
  8. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-DemiBold.woff +0 -0
  9. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-ExtraBlack.woff +0 -0
  10. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-ExtraBold.woff +0 -0
  11. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Heavy.woff +0 -0
  12. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Light.woff +0 -0
  13. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Medium.woff +0 -0
  14. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Regular.woff +0 -0
  15. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-Thin.woff +0 -0
  16. package/dist/fonts/IranYekan/Woff/IRANYekanXFaNum-UltraLight.woff +0 -0
  17. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Black.woff2 +0 -0
  18. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Bold.woff2 +0 -0
  19. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-DemiBold.woff2 +0 -0
  20. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-ExtraBlack.woff2 +0 -0
  21. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-ExtraBold.woff2 +0 -0
  22. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Heavy.woff2 +0 -0
  23. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Light.woff2 +0 -0
  24. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Medium.woff2 +0 -0
  25. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Regular.woff2 +0 -0
  26. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-Thin.woff2 +0 -0
  27. package/dist/fonts/IranYekan/Woff2/IRANYekanXFaNum-UltraLight.woff2 +0 -0
  28. package/dist/fonts/fonts.css +245 -0
  29. package/dist/hooks/index.js +107 -0
  30. package/dist/index.js +3831 -0
  31. package/dist/libs/index.js +142 -0
  32. package/dist/providers/index.js +305 -0
  33. package/dist/types/components/Accordion.d.ts +4 -0
  34. package/dist/types/components/AccordionDetails.d.ts +4 -0
  35. package/dist/types/components/AccordionSummary.d.ts +4 -0
  36. package/dist/types/components/Autocomplete.d.ts +3 -0
  37. package/dist/types/components/Box.d.ts +4 -0
  38. package/dist/types/components/Button.d.ts +9 -0
  39. package/dist/types/components/CardNumberInput.d.ts +13 -0
  40. package/dist/types/components/Checkbox.d.ts +11 -0
  41. package/dist/types/components/CircularProgress.d.ts +4 -0
  42. package/dist/types/components/Container.d.ts +4 -0
  43. package/dist/types/components/CounterBoxInput.d.ts +23 -0
  44. package/dist/types/components/DataGrid.d.ts +57 -0
  45. package/dist/types/components/Dialog.d.ts +4 -0
  46. package/dist/types/components/Divider.d.ts +4 -0
  47. package/dist/types/components/Drawer.d.ts +9 -0
  48. package/dist/types/components/Fab.d.ts +4 -0
  49. package/dist/types/components/FormControl.d.ts +4 -0
  50. package/dist/types/components/FormControlLabel.d.ts +4 -0
  51. package/dist/types/components/Grid.d.ts +4 -0
  52. package/dist/types/components/IconButton.d.ts +4 -0
  53. package/dist/types/components/Image.d.ts +12 -0
  54. package/dist/types/components/InputLabel.d.ts +4 -0
  55. package/dist/types/components/InputPhoneNumber.d.ts +15 -0
  56. package/dist/types/components/IosHiddenOtpInput.d.ts +6 -0
  57. package/dist/types/components/List.d.ts +4 -0
  58. package/dist/types/components/ListItem.d.ts +4 -0
  59. package/dist/types/components/Loading.d.ts +7 -0
  60. package/dist/types/components/LoadingModal.d.ts +6 -0
  61. package/dist/types/components/MenuItem.d.ts +4 -0
  62. package/dist/types/components/MobileDatePicker.d.ts +19 -0
  63. package/dist/types/components/Modal.d.ts +9 -0
  64. package/dist/types/components/MultiSelect.d.ts +14 -0
  65. package/dist/types/components/NumberInput.d.ts +19 -0
  66. package/dist/types/components/OtpInput.d.ts +16 -0
  67. package/dist/types/components/Pagination.d.ts +4 -0
  68. package/dist/types/components/ProgressBar.d.ts +10 -0
  69. package/dist/types/components/Radio.d.ts +4 -0
  70. package/dist/types/components/RadioGroup.d.ts +4 -0
  71. package/dist/types/components/Select.d.ts +4 -0
  72. package/dist/types/components/Skeleton.d.ts +4 -0
  73. package/dist/types/components/Slider.d.ts +4 -0
  74. package/dist/types/components/Step.d.ts +4 -0
  75. package/dist/types/components/StepConnector.d.ts +4 -0
  76. package/dist/types/components/StepContent.d.ts +4 -0
  77. package/dist/types/components/StepLabel.d.ts +4 -0
  78. package/dist/types/components/Stepper.d.ts +4 -0
  79. package/dist/types/components/SvgIcon.d.ts +8 -0
  80. package/dist/types/components/Tab.d.ts +12 -0
  81. package/dist/types/components/TextField.d.ts +9 -0
  82. package/dist/types/components/Toast.d.ts +20 -0
  83. package/dist/types/components/Toggle.d.ts +10 -0
  84. package/dist/types/components/Typography.d.ts +8 -0
  85. package/dist/types/components/WheelDatePicker.d.ts +37 -0
  86. package/dist/types/components/index.d.ts +53 -0
  87. package/dist/types/constants/colors.d.ts +2 -0
  88. package/dist/types/constants/index.d.ts +2 -0
  89. package/dist/types/constants/stepConnectorClasses.d.ts +2 -0
  90. package/dist/types/constants/typography.d.ts +82 -0
  91. package/dist/types/context/MessageHandler.d.ts +15 -0
  92. package/dist/types/context/index.d.ts +1 -0
  93. package/dist/types/hooks/index.d.ts +8 -0
  94. package/dist/types/hooks/useErrorHandler.d.ts +10 -0
  95. package/dist/types/hooks/useMessage.d.ts +2 -0
  96. package/dist/types/hooks/useWebOtpListener.d.ts +1 -0
  97. package/dist/types/index.d.ts +8 -0
  98. package/dist/types/index.js +19 -0
  99. package/dist/types/libs/create-api-request.d.ts +10 -0
  100. package/dist/types/libs/create-logger.d.ts +9 -0
  101. package/dist/types/libs/create-sentry-instrument.d.ts +9 -0
  102. package/dist/types/libs/index.d.ts +10 -0
  103. package/dist/types/providers/SPAThemeProvider.d.ts +11 -0
  104. package/dist/types/providers/ThemeProvider.d.ts +9 -0
  105. package/dist/types/providers/index.d.ts +2 -0
  106. package/dist/types/stories/persian.d.ts +81 -0
  107. package/dist/types/types/axios.d.ts +8 -0
  108. package/dist/types/types/color.d.ts +38 -0
  109. package/dist/types/types/index.d.ts +7 -0
  110. package/dist/types/types/material-react-table-types.d.ts +2 -0
  111. package/dist/types/types/mui-types.d.ts +2 -0
  112. package/dist/types/types/services.d.ts +26 -0
  113. package/dist/types/types/typography.d.ts +62 -0
  114. package/dist/types/types/window.d.ts +135 -0
  115. package/dist/types/utils/checkUser.d.ts +1 -0
  116. package/dist/types/utils/convertRialToToman.d.ts +7 -0
  117. package/dist/types/utils/createQueryParams.d.ts +3 -0
  118. package/dist/types/utils/dateHelpers.d.ts +19 -0
  119. package/dist/types/utils/delay.d.ts +1 -0
  120. package/dist/types/utils/formatPersianNumber.d.ts +1 -0
  121. package/dist/types/utils/getClaims.d.ts +11 -0
  122. package/dist/types/utils/index.d.ts +17 -0
  123. package/dist/types/utils/injastStyled.d.ts +2 -0
  124. package/dist/types/utils/postToParent.d.ts +2 -0
  125. package/dist/types/utils/toLatinDigit.d.ts +1 -0
  126. package/dist/utils/index.js +256 -0
  127. package/package.json +159 -0
package/dist/index.js ADDED
@@ -0,0 +1,3831 @@
1
+ "use client";
2
+
3
+ // src/components/Accordion.tsx
4
+ import { Accordion as MuiAccordion } from "@mui/material";
5
+ import { jsx } from "react/jsx-runtime";
6
+ var Accordion = ({ children, ...props }) => {
7
+ return /* @__PURE__ */ jsx(MuiAccordion, { ...props, children });
8
+ };
9
+ var Accordion_default = Accordion;
10
+
11
+ // src/components/AccordionDetails.tsx
12
+ import {
13
+ AccordionDetails as MuiAccordionDetails
14
+ } from "@mui/material";
15
+ import { jsx as jsx2 } from "react/jsx-runtime";
16
+ var AccordionDetails = ({
17
+ children,
18
+ ...props
19
+ }) => {
20
+ return /* @__PURE__ */ jsx2(MuiAccordionDetails, { ...props, children });
21
+ };
22
+ var AccordionDetails_default = AccordionDetails;
23
+
24
+ // src/components/AccordionSummary.tsx
25
+ import {
26
+ AccordionSummary as MuiAccordionSummary
27
+ } from "@mui/material";
28
+ import { jsx as jsx3 } from "react/jsx-runtime";
29
+ var AccordionSummary = ({
30
+ children,
31
+ ...props
32
+ }) => {
33
+ return /* @__PURE__ */ jsx3(MuiAccordionSummary, { ...props, children });
34
+ };
35
+ var AccordionSummary_default = AccordionSummary;
36
+
37
+ // src/components/Autocomplete.tsx
38
+ import {
39
+ Autocomplete as MuiAutocomplete
40
+ } from "@mui/material";
41
+ import { jsx as jsx4 } from "react/jsx-runtime";
42
+ var Autocomplete = (props) => {
43
+ return /* @__PURE__ */ jsx4(MuiAutocomplete, { ...props });
44
+ };
45
+ var Autocomplete_default = Autocomplete;
46
+
47
+ // src/components/Box.tsx
48
+ import { Box as MuiBox } from "@mui/material";
49
+ import { jsx as jsx5 } from "react/jsx-runtime";
50
+ var Box = ({ children, ...props }) => {
51
+ return /* @__PURE__ */ jsx5(MuiBox, { ...props, children });
52
+ };
53
+ var Box_default = Box;
54
+
55
+ // src/components/Button.tsx
56
+ import {
57
+ Button as MuiButton,
58
+ CircularProgress
59
+ } from "@mui/material";
60
+
61
+ // src/constants/colors.ts
62
+ var defaultColors = {
63
+ neutral: {
64
+ 50: "#F8FAFD",
65
+ 100: "#F4F6FA",
66
+ 200: "#E8EAEE",
67
+ 300: "#D6D9DF",
68
+ 400: "#B1B7C2",
69
+ 500: "#91969F",
70
+ 600: "#6B7079",
71
+ 700: "#4F545E",
72
+ 800: "#363C46",
73
+ 900: "#242933",
74
+ main: "#4F545E",
75
+ light: "#91969F",
76
+ dark: "#242933",
77
+ contrastText: "#fff"
78
+ },
79
+ success: {
80
+ dark: "#0B8922",
81
+ main: "#18AB33",
82
+ light: "#EAF9EC"
83
+ },
84
+ danger: {
85
+ dark: "#B9141F",
86
+ main: "#ED2C3A",
87
+ light: "#FEEAEC"
88
+ },
89
+ warning: {
90
+ dark: "#CB620A",
91
+ main: "#FD7E14",
92
+ light: "#FFEFE1"
93
+ },
94
+ info: {
95
+ dark: "#168EA1",
96
+ main: "#24ADC2",
97
+ light: "#E5F8FB"
98
+ },
99
+ yellow: {
100
+ 100: "#FFF3CD",
101
+ 200: "#FFDA6A",
102
+ 300: "#FFC107",
103
+ 400: "#DCA000",
104
+ dark: "#DCA000",
105
+ main: "#FFC107",
106
+ light: "#FFF3CD",
107
+ transparent: "#FFC1071A"
108
+ },
109
+ red: {
110
+ 100: "#FDEAEB",
111
+ 200: "#FF606F",
112
+ 300: "#ED2C3A",
113
+ 400: "#AC2633",
114
+ dark: "#AC2633",
115
+ main: "#ED2C3A",
116
+ light: "#FDEAEB",
117
+ transparent: "#ED2C3A1A"
118
+ },
119
+ indigo: {
120
+ 100: "#EEE3FF",
121
+ 200: "#8540F5",
122
+ 300: "#6610F2",
123
+ 400: "#3D0A91",
124
+ dark: "#3D0A91",
125
+ main: "#6610F2",
126
+ light: "#EEE3FF",
127
+ transparent: "#6610F21A"
128
+ },
129
+ cyan: {
130
+ 100: "#E5F8FB",
131
+ 200: "#6EDFF6",
132
+ 300: "#0DCAF0",
133
+ 400: "#24ADC2",
134
+ dark: "#24ADC2",
135
+ main: "#0DCAF0",
136
+ light: "#E5F8FB",
137
+ transparent: "#0DCAF01A"
138
+ },
139
+ pink: {
140
+ 100: "#FDECF0",
141
+ 200: "#FF6C88",
142
+ 300: "#EF4465",
143
+ 400: "#CC2C4B",
144
+ dark: "#CC2C4B",
145
+ main: "#EF4465",
146
+ light: "#FDECF0",
147
+ transparent: "#EF44651A"
148
+ },
149
+ orange: {
150
+ 100: "#FFEFE1",
151
+ 200: "#FD9843",
152
+ 300: "#FD7E14",
153
+ 400: "#A34A00",
154
+ dark: "#A34A00",
155
+ main: "#FD7E14",
156
+ light: "#FFEFE1",
157
+ transparent: "#FFC1071A"
158
+ },
159
+ magenta: {
160
+ 100: "#FCE3EF",
161
+ 200: "#DE5C9D",
162
+ 300: "#D63384",
163
+ 400: "#801F4F",
164
+ dark: "#801F4F",
165
+ main: "#D63384",
166
+ light: "#FCE3EF",
167
+ transparent: "#D633841A"
168
+ },
169
+ blue: {
170
+ 100: "#E3F2FF",
171
+ 200: "#5A9DFF",
172
+ 300: "#0D6EFD",
173
+ 400: "#084298",
174
+ dark: "#084298",
175
+ main: "#0D6EFD",
176
+ light: "#E3F2FF",
177
+ transparent: "#0D6EFD1A"
178
+ },
179
+ teal: {
180
+ 100: "#E5FAF4",
181
+ 200: "#79DFC1",
182
+ 300: "#20C997",
183
+ 400: "#179D76",
184
+ dark: "#179D76",
185
+ main: "#20C997",
186
+ light: "#E5FAF4",
187
+ transparent: "#20C9971A"
188
+ }
189
+ };
190
+
191
+ // src/components/Button.tsx
192
+ import { jsx as jsx6 } from "react/jsx-runtime";
193
+ var Button = ({
194
+ loading = false,
195
+ buttonSize = "M",
196
+ loadingColor = defaultColors.neutral[50],
197
+ children,
198
+ ...props
199
+ }) => {
200
+ const { sx: sxProp, onClick, ...restProps } = props;
201
+ const sizeStyles = {
202
+ L: {
203
+ fontSize: "1rem",
204
+ height: "56px",
205
+ borderRadius: "12px"
206
+ },
207
+ M: {
208
+ fontSize: "1rem",
209
+ height: "48px",
210
+ borderRadius: "12px"
211
+ },
212
+ S: {
213
+ fontSize: "0.875rem",
214
+ height: "40px",
215
+ borderRadius: "8px"
216
+ },
217
+ XS: {
218
+ fontSize: "0.75rem",
219
+ height: "32px",
220
+ borderRadius: "8px"
221
+ }
222
+ };
223
+ return /* @__PURE__ */ jsx6(
224
+ MuiButton,
225
+ {
226
+ disableRipple: true,
227
+ disableFocusRipple: true,
228
+ disableElevation: true,
229
+ disableTouchRipple: true,
230
+ onClick: loading ? void 0 : onClick,
231
+ sx: {
232
+ ...sxProp,
233
+ ...sizeStyles[buttonSize],
234
+ display: "flex",
235
+ gap: "8px",
236
+ alignItems: "center",
237
+ boxShadow: "none",
238
+ justifyContent: "center",
239
+ textTransform: "none",
240
+ fontWeight: 700,
241
+ "& .MuiButton-endIcon": {
242
+ margin: 0,
243
+ right: 0,
244
+ left: 0
245
+ },
246
+ "& .MuiButton-startIcon": {
247
+ margin: 0,
248
+ right: 0,
249
+ left: 0
250
+ },
251
+ "&.Mui-disabled": {
252
+ color: "neutral.300",
253
+ "&.MuiButton-contained": {
254
+ color: "neutral.light",
255
+ backgroundColor: "neutral.400",
256
+ borderColor: "neutral.400"
257
+ },
258
+ "&.MuiButton-outlined": {
259
+ color: "neutral.300",
260
+ borderColor: "neutral.200"
261
+ },
262
+ "& .MuiButton-startIcon": {
263
+ filter: "grayscale(1)"
264
+ }
265
+ }
266
+ },
267
+ ...restProps,
268
+ children: loading ? /* @__PURE__ */ jsx6(CircularProgress, { sx: { color: loadingColor }, size: 24 }) : children
269
+ }
270
+ );
271
+ };
272
+ var Button_default = Button;
273
+
274
+ // src/components/Checkbox.tsx
275
+ import {
276
+ Checkbox as MuiCheckbox,
277
+ useTheme
278
+ } from "@mui/material";
279
+ import { jsx as jsx7 } from "react/jsx-runtime";
280
+ var Checkbox = ({
281
+ iconSize = 24,
282
+ borderColor,
283
+ checkedBorderColor,
284
+ backgroundColor,
285
+ tickColor,
286
+ ...props
287
+ }) => {
288
+ const theme = useTheme();
289
+ return /* @__PURE__ */ jsx7(
290
+ MuiCheckbox,
291
+ {
292
+ disableRipple: true,
293
+ ...props,
294
+ icon: /* @__PURE__ */ jsx7(
295
+ "div",
296
+ {
297
+ style: {
298
+ width: iconSize,
299
+ height: iconSize,
300
+ border: `1px solid ${borderColor ? borderColor : "#D6D9DF"}`,
301
+ borderRadius: 4
302
+ }
303
+ }
304
+ ),
305
+ checkedIcon: /* @__PURE__ */ jsx7(
306
+ "div",
307
+ {
308
+ style: {
309
+ width: iconSize,
310
+ height: iconSize,
311
+ border: `1px solid ${theme.palette.primary.main || checkedBorderColor}`,
312
+ borderRadius: 4,
313
+ backgroundColor,
314
+ display: "flex",
315
+ justifyContent: "center",
316
+ alignItems: "center"
317
+ },
318
+ children: /* @__PURE__ */ jsx7(
319
+ "svg",
320
+ {
321
+ width: iconSize / 1.2,
322
+ height: iconSize / 1.2,
323
+ viewBox: "0 0 24 24",
324
+ fill: "none",
325
+ xmlns: "http://www.w3.org/2000/svg",
326
+ children: /* @__PURE__ */ jsx7(
327
+ "path",
328
+ {
329
+ d: "M9 16.2L4.8 12L3.4 13.4L9 19L21 7L19.6 5.6L9 16.2Z",
330
+ fill: theme.palette.primary.main || tickColor
331
+ }
332
+ )
333
+ }
334
+ )
335
+ }
336
+ )
337
+ }
338
+ );
339
+ };
340
+ var Checkbox_default = Checkbox;
341
+
342
+ // src/components/Container.tsx
343
+ import { Container as MuiContainer } from "@mui/material";
344
+ import { jsx as jsx8 } from "react/jsx-runtime";
345
+ var Container = ({ children, ...props }) => {
346
+ return /* @__PURE__ */ jsx8(MuiContainer, { ...props, children });
347
+ };
348
+ var Container_default = Container;
349
+
350
+ // src/components/Drawer.tsx
351
+ import { Drawer as MuiDrawer } from "@mui/material";
352
+ import { jsx as jsx9 } from "react/jsx-runtime";
353
+ var Drawer = ({
354
+ children,
355
+ isDrawerOpen,
356
+ onClose,
357
+ ...props
358
+ }) => {
359
+ const { sx: sxProp, ...restProps } = props;
360
+ return /* @__PURE__ */ jsx9(
361
+ MuiDrawer,
362
+ {
363
+ anchor: "bottom",
364
+ open: isDrawerOpen,
365
+ onClose,
366
+ dir: "rtl",
367
+ ...restProps,
368
+ sx: {
369
+ ...sxProp,
370
+ backdropFilter: "blur(2px)",
371
+ backgroundColor: "rgba(0,0,30,0.4)",
372
+ "&.MuiDrawer-anchorBottom": {
373
+ "& .MuiPaper-root": {
374
+ borderRadius: "12px 12px 0 0"
375
+ }
376
+ }
377
+ },
378
+ children
379
+ }
380
+ );
381
+ };
382
+ var Drawer_default = Drawer;
383
+
384
+ // src/components/FormControl.tsx
385
+ import { FormControl as MuiFormControl } from "@mui/material";
386
+ import { jsx as jsx10 } from "react/jsx-runtime";
387
+ var FormControl = ({ children, ...props }) => {
388
+ return /* @__PURE__ */ jsx10(MuiFormControl, { ...props, children });
389
+ };
390
+ var FormControl_default = FormControl;
391
+
392
+ // src/components/Grid.tsx
393
+ import { Grid2 } from "@mui/material";
394
+ import { jsx as jsx11 } from "react/jsx-runtime";
395
+ var Grid = ({ children, ...props }) => {
396
+ return /* @__PURE__ */ jsx11(Grid2, { ...props, children });
397
+ };
398
+ var Grid_default = Grid;
399
+
400
+ // src/components/IconButton.tsx
401
+ import { IconButton as MuiIconButton } from "@mui/material";
402
+ import { jsx as jsx12 } from "react/jsx-runtime";
403
+ var IconButton = ({ children, ...props }) => {
404
+ return /* @__PURE__ */ jsx12(MuiIconButton, { disableRipple: true, ...props, children });
405
+ };
406
+ var IconButton_default = IconButton;
407
+
408
+ // src/components/InputLabel.tsx
409
+ import { InputLabel as MuiInputLabel } from "@mui/material";
410
+ import { jsx as jsx13 } from "react/jsx-runtime";
411
+ var InputLabel = ({ children, ...props }) => {
412
+ return /* @__PURE__ */ jsx13(MuiInputLabel, { ...props, children });
413
+ };
414
+ var InputLabel_default = InputLabel;
415
+
416
+ // src/components/Loading.tsx
417
+ import { CircularProgress as CircularProgress2, Container as Container2 } from "@mui/material";
418
+ import { jsx as jsx14 } from "react/jsx-runtime";
419
+ var Loading = ({ color, size = 50 }) => {
420
+ return /* @__PURE__ */ jsx14(
421
+ Container2,
422
+ {
423
+ sx: {
424
+ width: "100%",
425
+ display: "flex",
426
+ flexDirection: "row",
427
+ alignItems: "center",
428
+ justifyContent: "center"
429
+ },
430
+ children: /* @__PURE__ */ jsx14(CircularProgress2, { size, sx: { color } })
431
+ }
432
+ );
433
+ };
434
+ var Loading_default = Loading;
435
+
436
+ // src/components/MenuItem.tsx
437
+ import { MenuItem as MuiMenuItem } from "@mui/material";
438
+ import { jsx as jsx15 } from "react/jsx-runtime";
439
+ var MenuItem = ({ children, ...props }) => {
440
+ return /* @__PURE__ */ jsx15(MuiMenuItem, { ...props, children });
441
+ };
442
+ var MenuItem_default = MenuItem;
443
+
444
+ // src/components/Modal.tsx
445
+ import { Dialog, DialogContent } from "@mui/material";
446
+
447
+ // src/utils/injastStyled.ts
448
+ import { styled as muiStyled } from "@mui/material/styles";
449
+
450
+ // src/components/Modal.tsx
451
+ import { jsx as jsx16 } from "react/jsx-runtime";
452
+ var CustomBackdrop = muiStyled("div")(({}) => ({
453
+ position: "fixed",
454
+ top: 0,
455
+ left: 0,
456
+ width: "100vw",
457
+ height: "100vh",
458
+ backgroundColor: "rgba(0,0,20,0.65)",
459
+ backdropFilter: "blur(2px)",
460
+ zIndex: -1
461
+ }));
462
+ var Modal = ({ open, onClose, children, width }) => {
463
+ return /* @__PURE__ */ jsx16(
464
+ Dialog,
465
+ {
466
+ open,
467
+ onClose,
468
+ maxWidth: width ? false : void 0,
469
+ slots: {
470
+ backdrop: CustomBackdrop
471
+ },
472
+ PaperProps: {
473
+ sx: {
474
+ borderRadius: 3,
475
+ margin: 2
476
+ }
477
+ },
478
+ children: /* @__PURE__ */ jsx16(DialogContent, { sx: { width }, children })
479
+ }
480
+ );
481
+ };
482
+ var Modal_default = Modal;
483
+
484
+ // src/components/ProgressBar.tsx
485
+ import { Box as Box2, LinearProgress, Typography } from "@mui/material";
486
+ import { jsx as jsx17, jsxs } from "react/jsx-runtime";
487
+ var ProgressBar = ({
488
+ color,
489
+ progress,
490
+ height = 20,
491
+ disablePercentage,
492
+ isRtl
493
+ }) => {
494
+ return /* @__PURE__ */ jsxs(
495
+ Box2,
496
+ {
497
+ sx: { position: "relative", transform: `${isRtl && "rotateY(180deg)"}` },
498
+ children: [
499
+ /* @__PURE__ */ jsx17(Box2, { sx: { width: "100%" }, children: /* @__PURE__ */ jsx17(
500
+ LinearProgress,
501
+ {
502
+ sx: {
503
+ height: height ? `${height}px` : "20px",
504
+ borderRadius: "9999px",
505
+ backgroundColor: progress > 0 ? `#E8EAEE` : `#F4F6FA`,
506
+ "& .MuiLinearProgress-bar1Determinate": {
507
+ borderRadius: "9999px",
508
+ backgroundColor: color
509
+ }
510
+ },
511
+ variant: "determinate",
512
+ value: progress
513
+ }
514
+ ) }),
515
+ !disablePercentage && /* @__PURE__ */ jsx17(
516
+ Typography,
517
+ {
518
+ variant: "label1",
519
+ sx: {
520
+ position: "absolute",
521
+ fontWeight: "500",
522
+ left: progress > 90 ? "50%" : "16px",
523
+ top: "60%",
524
+ transform: `translate(-50%,-50%) ${isRtl ? "rotateY(180deg)" : ""}`,
525
+ color: progress > 90 ? "white" : `#242933`
526
+ },
527
+ children: `${Math.round(progress)}%`
528
+ }
529
+ )
530
+ ]
531
+ }
532
+ );
533
+ };
534
+ var ProgressBar_default = ProgressBar;
535
+
536
+ // src/components/Radio.tsx
537
+ import { Radio as MuiRadio } from "@mui/material";
538
+ import { jsx as jsx18 } from "react/jsx-runtime";
539
+ var Radio = ({ ...props }) => {
540
+ return /* @__PURE__ */ jsx18(MuiRadio, { ...props });
541
+ };
542
+ var Radio_default = Radio;
543
+
544
+ // src/components/Select.tsx
545
+ import { Select as MuiSelect } from "@mui/material";
546
+ import { jsx as jsx19 } from "react/jsx-runtime";
547
+ var Select = ({ children, ...props }) => {
548
+ return /* @__PURE__ */ jsx19(MuiSelect, { ...props, children });
549
+ };
550
+ var Select_default = Select;
551
+
552
+ // src/components/Skeleton.tsx
553
+ import { Skeleton as MuiSkeleton } from "@mui/material";
554
+ import { jsx as jsx20 } from "react/jsx-runtime";
555
+ var Skeleton = ({ ...props }) => {
556
+ return /* @__PURE__ */ jsx20(MuiSkeleton, { ...props });
557
+ };
558
+ var Skeleton_default = Skeleton;
559
+
560
+ // src/components/Step.tsx
561
+ import { Step as MuiStep } from "@mui/material";
562
+ import { jsx as jsx21 } from "react/jsx-runtime";
563
+ var Step = ({ children, ...props }) => {
564
+ return /* @__PURE__ */ jsx21(MuiStep, { ...props, children });
565
+ };
566
+ var Step_default = Step;
567
+
568
+ // src/components/StepConnector.tsx
569
+ import {
570
+ StepConnector as MuiStepConnector
571
+ } from "@mui/material";
572
+ import { jsx as jsx22 } from "react/jsx-runtime";
573
+ var StepConnector = ({ ...props }) => {
574
+ return /* @__PURE__ */ jsx22(MuiStepConnector, { ...props });
575
+ };
576
+ var StepConnector_default = StepConnector;
577
+
578
+ // src/components/StepContent.tsx
579
+ import { StepContent as MuiStepContent } from "@mui/material";
580
+ import { jsx as jsx23 } from "react/jsx-runtime";
581
+ var StepContent = ({ children, ...props }) => {
582
+ return /* @__PURE__ */ jsx23(MuiStepContent, { ...props, children });
583
+ };
584
+ var StepContent_default = StepContent;
585
+
586
+ // src/components/StepLabel.tsx
587
+ import { StepLabel as MuiStepLabel } from "@mui/material";
588
+ import { jsx as jsx24 } from "react/jsx-runtime";
589
+ var StepLabel = ({ children, ...props }) => {
590
+ return /* @__PURE__ */ jsx24(MuiStepLabel, { ...props, children });
591
+ };
592
+ var StepLabel_default = StepLabel;
593
+
594
+ // src/components/Stepper.tsx
595
+ import { Stepper as MuiStepper } from "@mui/material";
596
+ import { jsx as jsx25 } from "react/jsx-runtime";
597
+ var Stepper = ({ children, ...props }) => {
598
+ return /* @__PURE__ */ jsx25(MuiStepper, { ...props, children });
599
+ };
600
+ var Stepper_default = Stepper;
601
+
602
+ // src/components/TextField.tsx
603
+ import {
604
+ InputAdornment,
605
+ TextField as MuiTextField
606
+ } from "@mui/material";
607
+ import { mergeSlotProps } from "@mui/material/utils";
608
+ import { jsx as jsx26 } from "react/jsx-runtime";
609
+ var TextField = ({
610
+ startAdornment,
611
+ endAdornment,
612
+ height,
613
+ ...props
614
+ }) => {
615
+ const { sx: sxProp, slotProps: slotPropsProp, ...restProps } = props;
616
+ const defaultInputSlotProps = {
617
+ startAdornment: startAdornment && /* @__PURE__ */ jsx26(InputAdornment, { position: "start", children: startAdornment }),
618
+ endAdornment: endAdornment && /* @__PURE__ */ jsx26(InputAdornment, { position: "end", children: endAdornment })
619
+ };
620
+ const mergedSlotProps = {
621
+ ...slotPropsProp,
622
+ input: mergeSlotProps(slotPropsProp?.input, defaultInputSlotProps)
623
+ };
624
+ return /* @__PURE__ */ jsx26(
625
+ MuiTextField,
626
+ {
627
+ ...restProps,
628
+ slotProps: mergedSlotProps,
629
+ sx: {
630
+ ...sxProp,
631
+ height,
632
+ "& .MuiInputBase-root": { height },
633
+ "& .MuiOutlinedInput-root": {
634
+ borderRadius: 2,
635
+ height
636
+ },
637
+ "& .MuiFormHelperText-root": {
638
+ mx: 0
639
+ }
640
+ }
641
+ }
642
+ );
643
+ };
644
+ var TextField_default = TextField;
645
+
646
+ // src/components/Toast.tsx
647
+ import { Alert, Snackbar } from "@mui/material";
648
+ import { CloseCircle, Danger, InfoCircle, TickCircle } from "iconsax-react";
649
+ import { Fragment, jsx as jsx27 } from "react/jsx-runtime";
650
+ var Toast = ({
651
+ message,
652
+ open,
653
+ duration,
654
+ width = "90%",
655
+ handleClose,
656
+ anchorOrigin = { vertical: "top", horizontal: "left" },
657
+ isWide = false
658
+ }) => {
659
+ const getStyles = (severity) => {
660
+ const styles = {
661
+ error: {
662
+ backgroundColor: defaultColors.danger.light,
663
+ color: defaultColors.danger.main,
664
+ borderColor: defaultColors.danger.main
665
+ },
666
+ warning: {
667
+ backgroundColor: defaultColors.warning.light,
668
+ color: defaultColors.warning.main,
669
+ borderColor: defaultColors.warning.main
670
+ },
671
+ info: {
672
+ backgroundColor: defaultColors.info.light,
673
+ color: defaultColors.info.main,
674
+ borderColor: defaultColors.info.main
675
+ },
676
+ success: {
677
+ backgroundColor: defaultColors.success.light,
678
+ color: defaultColors.success.main,
679
+ borderColor: defaultColors.success.main
680
+ }
681
+ };
682
+ return styles[severity] || {};
683
+ };
684
+ const getIconForSeverity = (severity) => {
685
+ const icons = {
686
+ error: /* @__PURE__ */ jsx27(
687
+ CloseCircle,
688
+ {
689
+ color: defaultColors.danger.main,
690
+ size: 28,
691
+ variant: "Bold"
692
+ }
693
+ ),
694
+ warning: /* @__PURE__ */ jsx27(Danger, { color: defaultColors.warning.main, size: 28, variant: "Bold" }),
695
+ info: /* @__PURE__ */ jsx27(InfoCircle, { color: defaultColors.info.main, size: 28, variant: "Bold" }),
696
+ success: /* @__PURE__ */ jsx27(
697
+ TickCircle,
698
+ {
699
+ color: defaultColors.success.main,
700
+ size: 28,
701
+ variant: "Bold"
702
+ }
703
+ )
704
+ };
705
+ return icons[severity];
706
+ };
707
+ return /* @__PURE__ */ jsx27(
708
+ Snackbar,
709
+ {
710
+ open,
711
+ autoHideDuration: duration,
712
+ onClose: handleClose,
713
+ onClick: handleClose,
714
+ anchorOrigin,
715
+ sx: {
716
+ margin: "8px",
717
+ ...!isWide && anchorOrigin.horizontal === "center" && {
718
+ left: "50% !important",
719
+ right: "auto !important",
720
+ transform: "translateX(-50%)",
721
+ "@media (min-width: 600px)": {
722
+ left: "50% !important",
723
+ right: "auto !important",
724
+ transform: "translateX(-50%)"
725
+ }
726
+ },
727
+ ...!isWide && anchorOrigin.horizontal === "left" && {
728
+ "@media (min-width: 600px)": {
729
+ left: "50% !important",
730
+ right: "auto !important",
731
+ transform: "translateX(-50%)",
732
+ marginLeft: "-60px"
733
+ // نصف عرض container (550px / 2)
734
+ }
735
+ },
736
+ ...!isWide && anchorOrigin.horizontal === "right" && {
737
+ "@media (min-width: 600px)": {
738
+ left: "50% !important",
739
+ right: "auto !important",
740
+ transform: "translateX(-50%)",
741
+ marginLeft: "-60px"
742
+ // نصف عرض container (550px / 2)
743
+ }
744
+ }
745
+ },
746
+ children: message ? /* @__PURE__ */ jsx27(
747
+ Alert,
748
+ {
749
+ variant: "outlined",
750
+ icon: getIconForSeverity(message.severity),
751
+ severity: message.severity,
752
+ sx: {
753
+ width,
754
+ maxWidth: 450,
755
+ minWidth: isWide ? 350 : "auto",
756
+ borderRadius: "8px",
757
+ px: 3.5,
758
+ py: 4,
759
+ display: "flex",
760
+ alignItems: "center",
761
+ fontSize: "16px",
762
+ fontWeight: 500,
763
+ gap: 1,
764
+ ...getStyles(message.severity)
765
+ },
766
+ children: message.text
767
+ }
768
+ ) : /* @__PURE__ */ jsx27(Fragment, {})
769
+ }
770
+ );
771
+ };
772
+ var Toast_default = Toast;
773
+
774
+ // src/components/Toggle.tsx
775
+ import { styled, Switch } from "@mui/material";
776
+ import { jsx as jsx28 } from "react/jsx-runtime";
777
+ var Toggle = ({
778
+ size = "small",
779
+ color,
780
+ checked,
781
+ disabled,
782
+ onChange
783
+ }) => {
784
+ const InjastSwitch = styled((props) => /* @__PURE__ */ jsx28(
785
+ Switch,
786
+ {
787
+ focusVisibleClassName: ".Mui-focusVisible",
788
+ disableRipple: true,
789
+ size,
790
+ checked,
791
+ disabled,
792
+ onChange,
793
+ ...props
794
+ }
795
+ ))(({ theme }) => ({
796
+ width: size === "small" ? 48 : 59,
797
+ height: size === "small" ? 26 : 32,
798
+ padding: 0,
799
+ "& .MuiSwitch-switchBase": {
800
+ padding: 0,
801
+ margin: 2,
802
+ transitionDuration: "300ms",
803
+ "&.Mui-checked": {
804
+ transform: `translateX(${size === "small" ? 22 : 27}px)`,
805
+ color: "#fff",
806
+ "& + .MuiSwitch-track": {
807
+ backgroundColor: `${theme.palette.primary.main || color}`,
808
+ opacity: 1,
809
+ border: 0,
810
+ ...theme.applyStyles("dark", {
811
+ backgroundColor: `${theme.palette.primary.light || color}`
812
+ })
813
+ },
814
+ "&.Mui-disabled + .MuiSwitch-track": {
815
+ opacity: 0.5
816
+ }
817
+ },
818
+ "&.Mui-focusVisible .MuiSwitch-thumb": {
819
+ color: "#33cf4d",
820
+ border: "6px solid #fff"
821
+ },
822
+ "&.Mui-disabled .MuiSwitch-thumb": {
823
+ color: "#F4F6FA",
824
+ ...theme.applyStyles("dark", {
825
+ color: "#6B7079"
826
+ })
827
+ },
828
+ "&.Mui-disabled + .MuiSwitch-track": {
829
+ opacity: 0.7,
830
+ ...theme.applyStyles("dark", {
831
+ opacity: 0.3
832
+ })
833
+ }
834
+ },
835
+ "& .MuiSwitch-thumb": {
836
+ boxSizing: "border-box",
837
+ width: size === "small" ? 22 : 28,
838
+ height: size === "small" ? 22 : 28
839
+ },
840
+ "& .MuiSwitch-track": {
841
+ borderRadius: size === "small" ? 26 : 32 / 2,
842
+ backgroundColor: "#B1B7C2",
843
+ // bg color
844
+ opacity: 1,
845
+ transition: theme.transitions.create(["background-color"], {
846
+ duration: 500
847
+ }),
848
+ ...theme.applyStyles("dark", {
849
+ backgroundColor: "#39393D"
850
+ })
851
+ }
852
+ }));
853
+ return /* @__PURE__ */ jsx28(InjastSwitch, { sx: { m: 1 } });
854
+ };
855
+ var Toggle_default = Toggle;
856
+
857
+ // src/components/Typography.tsx
858
+ import {
859
+ Typography as MuiTypography
860
+ } from "@mui/material";
861
+ import { jsx as jsx29 } from "react/jsx-runtime";
862
+ var Typography2 = ({ children, ...props }) => {
863
+ return /* @__PURE__ */ jsx29(MuiTypography, { ...props, children });
864
+ };
865
+ var Typography_default = Typography2;
866
+
867
+ // src/components/OtpInput.tsx
868
+ import * as React from "react";
869
+ import { Box as Box3, styled as styled2 } from "@mui/system";
870
+ import { TextField as TextField2 } from "@mui/material";
871
+ import { jsx as jsx30, jsxs as jsxs2 } from "react/jsx-runtime";
872
+ var normalizeDigits = (str) => str.replace(/[\u06F0-\u06F9]/g, (d) => String(d.charCodeAt(0) - 1776)).replace(/[\u0660-\u0669]/g, (d) => String(d.charCodeAt(0) - 1632));
873
+ var onlyDigits = (str) => normalizeDigits(str).replace(/[^0-9]/g, "");
874
+ var InputElement = styled2("input")(
875
+ ({
876
+ theme,
877
+ width = "54px",
878
+ height = "54px",
879
+ backgroundColor,
880
+ focusedBorderColor,
881
+ error
882
+ }) => `
883
+ width: ${width};
884
+ height: ${height};
885
+ font-family: inherit;
886
+ font-size: 0.875rem;
887
+ font-weight: 400;
888
+ padding: 8px 0;
889
+ border-radius: 8px;
890
+ text-align: center;
891
+ color: ${defaultColors.neutral[900]};
892
+ background: ${backgroundColor};
893
+ border: 1px solid ${error ? defaultColors.danger.main : defaultColors.neutral[300]};
894
+ direction: ltr;
895
+
896
+ -moz-appearance: textfield;
897
+
898
+ &::-webkit-outer-spin-button,
899
+ &::-webkit-inner-spin-button {
900
+ -webkit-appearance: none;
901
+ margin: 0;
902
+ }
903
+
904
+ &:focus {
905
+ border-color: ${focusedBorderColor || defaultColors.neutral[300]};
906
+ box-shadow: 0 0 0 1px ${backgroundColor};
907
+ }
908
+
909
+ &:focus-visible {
910
+ outline: 0;
911
+ }
912
+ `
913
+ );
914
+ function OTP({
915
+ separator,
916
+ length: length2,
917
+ value,
918
+ onChange,
919
+ inputProps
920
+ }) {
921
+ const inputRefs = React.useRef(
922
+ new Array(length2).fill(null)
923
+ );
924
+ const focusInput = (targetIndex) => {
925
+ const targetInput = inputRefs.current[targetIndex];
926
+ targetInput?.focus();
927
+ };
928
+ const selectInput = (targetIndex) => {
929
+ const targetInput = inputRefs.current[targetIndex];
930
+ targetInput?.select();
931
+ };
932
+ const handleKeyDown2 = (event, currentIndex) => {
933
+ switch (event.key) {
934
+ case "ArrowUp":
935
+ case "ArrowDown":
936
+ case " ":
937
+ event.preventDefault();
938
+ break;
939
+ case "ArrowLeft":
940
+ event.preventDefault();
941
+ if (currentIndex > 0) {
942
+ focusInput(currentIndex - 1);
943
+ selectInput(currentIndex - 1);
944
+ }
945
+ break;
946
+ case "ArrowRight":
947
+ event.preventDefault();
948
+ if (currentIndex < length2 - 1) {
949
+ focusInput(currentIndex + 1);
950
+ selectInput(currentIndex + 1);
951
+ }
952
+ break;
953
+ case "Delete":
954
+ event.preventDefault();
955
+ onChange((prevOtp) => {
956
+ const otp = prevOtp.slice(0, currentIndex) + prevOtp.slice(currentIndex + 1);
957
+ return otp;
958
+ });
959
+ break;
960
+ case "Backspace":
961
+ event.preventDefault();
962
+ if (currentIndex > 0) {
963
+ focusInput(currentIndex - 1);
964
+ selectInput(currentIndex - 1);
965
+ }
966
+ onChange((prevOtp) => {
967
+ const otp = prevOtp.slice(0, currentIndex) + prevOtp.slice(currentIndex + 1);
968
+ return otp;
969
+ });
970
+ break;
971
+ default:
972
+ break;
973
+ }
974
+ };
975
+ const handleChange = (event, currentIndex) => {
976
+ const currentValue = onlyDigits(event.target.value);
977
+ let indexToEnter = 0;
978
+ while (indexToEnter <= currentIndex) {
979
+ if (inputRefs.current[indexToEnter]?.value && indexToEnter < currentIndex) {
980
+ indexToEnter += 1;
981
+ } else {
982
+ break;
983
+ }
984
+ }
985
+ onChange((prev) => {
986
+ const otpArray = prev.split("");
987
+ const lastValue = currentValue.slice(-1);
988
+ if (lastValue) otpArray[indexToEnter] = lastValue;
989
+ return otpArray.join("");
990
+ });
991
+ if (currentValue !== "" && currentIndex < length2 - 1) {
992
+ focusInput(currentIndex + 1);
993
+ }
994
+ };
995
+ const handleClick = (event, currentIndex) => {
996
+ selectInput(currentIndex);
997
+ };
998
+ const handlePaste = (event, currentIndex) => {
999
+ event.preventDefault();
1000
+ const clipboardData = event.clipboardData;
1001
+ if (clipboardData.types.includes("text/plain")) {
1002
+ let pastedText = onlyDigits(clipboardData.getData("text/plain")).slice(
1003
+ 0,
1004
+ length2
1005
+ );
1006
+ let indexToEnter = 0;
1007
+ while (indexToEnter <= currentIndex) {
1008
+ if (inputRefs.current[indexToEnter]?.value && indexToEnter < currentIndex) {
1009
+ indexToEnter += 1;
1010
+ } else {
1011
+ break;
1012
+ }
1013
+ }
1014
+ const otpArray = value.split("");
1015
+ for (let i = indexToEnter; i < length2; i += 1) {
1016
+ const next = pastedText[i - indexToEnter];
1017
+ if (!next) break;
1018
+ otpArray[i] = next;
1019
+ }
1020
+ onChange(otpArray.join(""));
1021
+ }
1022
+ };
1023
+ return /* @__PURE__ */ jsx30(
1024
+ Box3,
1025
+ {
1026
+ sx: {
1027
+ display: "flex",
1028
+ alignItems: "center",
1029
+ justifyContent: "space-between",
1030
+ width: "100%",
1031
+ gap: 0.5
1032
+ },
1033
+ children: new Array(length2).fill(null).map((_, index) => /* @__PURE__ */ jsxs2(React.Fragment, { children: [
1034
+ /* @__PURE__ */ jsx30(
1035
+ TextField2,
1036
+ {
1037
+ type: "tel",
1038
+ inputMode: "tel",
1039
+ autoComplete: "one-time-code",
1040
+ slotProps: {
1041
+ htmlInput: {
1042
+ pattern: "[0-9\u06F0-\u06F9\u0660-\u0669]*",
1043
+ inputMode: "tel",
1044
+ dir: "ltr",
1045
+ "aria-label": `Digit ${index + 1} of OTP`
1046
+ },
1047
+ input: {
1048
+ ref: (ele) => {
1049
+ inputRefs.current[index] = ele;
1050
+ },
1051
+ onKeyDown: (event) => handleKeyDown2(event, index),
1052
+ onChange: (event) => handleChange(event, index),
1053
+ onClick: (event) => handleClick(event, index),
1054
+ onPaste: (event) => handlePaste(event, index),
1055
+ value: value[index] ?? "",
1056
+ ...inputProps
1057
+ }
1058
+ },
1059
+ slots: {
1060
+ input: InputElement
1061
+ }
1062
+ }
1063
+ ),
1064
+ index === length2 - 1 ? null : separator
1065
+ ] }, index))
1066
+ }
1067
+ );
1068
+ }
1069
+ function OtpInput({
1070
+ separator = /* @__PURE__ */ jsx30("span", {}),
1071
+ length: length2,
1072
+ value,
1073
+ onChange,
1074
+ inputProps
1075
+ }) {
1076
+ return /* @__PURE__ */ jsx30(Box3, { sx: { display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsx30(
1077
+ OTP,
1078
+ {
1079
+ separator,
1080
+ value,
1081
+ onChange,
1082
+ length: length2,
1083
+ inputProps
1084
+ }
1085
+ ) });
1086
+ }
1087
+
1088
+ // src/components/Divider.tsx
1089
+ import { Divider as MuiDivider } from "@mui/material";
1090
+ import { jsx as jsx31 } from "react/jsx-runtime";
1091
+ var Divider = ({ ...props }) => {
1092
+ return /* @__PURE__ */ jsx31(MuiDivider, { ...props });
1093
+ };
1094
+ var Divider_default = Divider;
1095
+
1096
+ // src/components/FormControlLabel.tsx
1097
+ import {
1098
+ FormControlLabel as MuiFormControlLabel
1099
+ } from "@mui/material";
1100
+ import { jsx as jsx32 } from "react/jsx-runtime";
1101
+ var FormControlLabel = ({ ...props }) => {
1102
+ return /* @__PURE__ */ jsx32(MuiFormControlLabel, { ...props });
1103
+ };
1104
+ var FormControlLabel_default = FormControlLabel;
1105
+
1106
+ // src/components/RadioGroup.tsx
1107
+ import { RadioGroup as MuiRadioGroup } from "@mui/material";
1108
+ import { jsx as jsx33 } from "react/jsx-runtime";
1109
+ var RadioGroup = ({ children, ...props }) => {
1110
+ return /* @__PURE__ */ jsx33(MuiRadioGroup, { ...props, children });
1111
+ };
1112
+ var RadioGroup_default = RadioGroup;
1113
+
1114
+ // src/components/Slider.tsx
1115
+ import { Slider as MuiSlider } from "@mui/material";
1116
+ import { jsx as jsx34 } from "react/jsx-runtime";
1117
+ var Slider = ({ ...props }) => {
1118
+ return /* @__PURE__ */ jsx34(MuiSlider, { ...props });
1119
+ };
1120
+ var Slider_default = Slider;
1121
+
1122
+ // src/components/List.tsx
1123
+ import { List as MuiList } from "@mui/material";
1124
+ import { jsx as jsx35 } from "react/jsx-runtime";
1125
+ var List = ({ children, ...props }) => {
1126
+ return /* @__PURE__ */ jsx35(MuiList, { ...props, children });
1127
+ };
1128
+ var List_default = List;
1129
+
1130
+ // src/components/ListItem.tsx
1131
+ import { ListItem as MuiListItem } from "@mui/material";
1132
+ import { jsx as jsx36 } from "react/jsx-runtime";
1133
+ var ListItem = ({ children, ...props }) => {
1134
+ return /* @__PURE__ */ jsx36(MuiListItem, { ...props, children });
1135
+ };
1136
+ var ListItem_default = ListItem;
1137
+
1138
+ // src/components/MobileDatePicker.tsx
1139
+ import { useState, useRef as useRef2, useEffect } from "react";
1140
+ import { Calendar } from "react-multi-date-picker";
1141
+ import persian from "react-date-object/calendars/persian";
1142
+ import persian_fa from "react-date-object/locales/persian_fa";
1143
+ import "react-multi-date-picker/styles/layouts/mobile.css";
1144
+ import { Calendar as CalendarIcon } from "iconsax-react";
1145
+
1146
+ // src/utils/dateHelpers.ts
1147
+ import PN from "persian-number";
1148
+ import { toJalaali, toGregorian } from "jalaali-js";
1149
+ function gregorianToJalali(dateString) {
1150
+ const [year, month, day] = dateString.split("-").map(Number);
1151
+ const jalaliDate = toJalaali(year, month, day);
1152
+ const formattedMonth = String(jalaliDate.jm).padStart(2, "0");
1153
+ const formattedDay = String(jalaliDate.jd).padStart(2, "0");
1154
+ return `${jalaliDate.jy}/${formattedMonth}/${formattedDay}`;
1155
+ }
1156
+ function jalaliToGregorian(dateString) {
1157
+ const [year, month, day] = dateString.split("/").map(Number);
1158
+ const gregorianDate = toGregorian(year, month, day);
1159
+ const formattedMonth = String(gregorianDate.gm).padStart(2, "0");
1160
+ const formattedDay = String(gregorianDate.gd).padStart(2, "0");
1161
+ return `${gregorianDate.gy}-${formattedMonth}-${formattedDay}`;
1162
+ }
1163
+ var normalizeTimestamp = (timestamp) => {
1164
+ const MILLISECOND_TIMESTAMP_LENGTH = 13;
1165
+ const isMilliseconds = timestamp.toString().length === MILLISECOND_TIMESTAMP_LENGTH;
1166
+ const normalizedTimestamp = isMilliseconds ? timestamp : timestamp * 1e3;
1167
+ if (normalizedTimestamp <= 0) return 0;
1168
+ return normalizedTimestamp;
1169
+ };
1170
+ var createDate = (t) => {
1171
+ const invalidDate = "invalid time";
1172
+ if (typeof t === "string") {
1173
+ const d = new Date(t);
1174
+ if (!isNaN(d.getTime())) return d;
1175
+ else return invalidDate;
1176
+ } else if (typeof t === "number") {
1177
+ const ts = normalizeTimestamp(t);
1178
+ const d = new Date(ts);
1179
+ if (!isNaN(d.getTime())) return d;
1180
+ else return invalidDate;
1181
+ } else return invalidDate;
1182
+ };
1183
+ var shortDateFormat = (timestamp) => {
1184
+ const date = createDate(timestamp);
1185
+ return date instanceof Date ? new Intl.DateTimeFormat("fa-IR").format(date) : date;
1186
+ };
1187
+ var longDateFormat = (timestamp, separator = "-") => {
1188
+ const date = createDate(timestamp);
1189
+ const dateOptions = {
1190
+ year: "numeric",
1191
+ month: "2-digit",
1192
+ day: "2-digit",
1193
+ localeMatcher: "best fit"
1194
+ };
1195
+ const timeOptions = {
1196
+ hour: "2-digit",
1197
+ minute: "2-digit",
1198
+ second: "2-digit",
1199
+ hour12: false,
1200
+ // Use 24-hour format
1201
+ localeMatcher: "best fit"
1202
+ };
1203
+ if (date instanceof Date) {
1204
+ const formattedDate = new Intl.DateTimeFormat("fa-IR", dateOptions).format(
1205
+ date
1206
+ );
1207
+ const formattedTime = new Intl.DateTimeFormat("fa-IR", timeOptions).format(
1208
+ date
1209
+ );
1210
+ return `${formattedDate} ${separator} ${formattedTime}`;
1211
+ } else {
1212
+ return date;
1213
+ }
1214
+ };
1215
+ var longFormatInWords = (timestamp, options = {
1216
+ dayInWord: true,
1217
+ monthInWord: true,
1218
+ yearInWord: true,
1219
+ showTime: false,
1220
+ showSeconds: true,
1221
+ separator: "-"
1222
+ }) => {
1223
+ const date = createDate(timestamp);
1224
+ const {
1225
+ dayInWord,
1226
+ monthInWord,
1227
+ yearInWord,
1228
+ separator,
1229
+ showTime,
1230
+ showSeconds
1231
+ } = options;
1232
+ if (date instanceof Date) {
1233
+ const formatter = new Intl.DateTimeFormat("fa-IR-u-nu-latn", {
1234
+ day: "numeric",
1235
+ month: monthInWord ? "long" : "numeric",
1236
+ year: "numeric"
1237
+ });
1238
+ const [day, , month, , year] = formatter.formatToParts(date);
1239
+ const formattedDay = dayInWord ? `${PN.convert(day.value)}` : day.value;
1240
+ const formattedYear = yearInWord ? `${PN.convert(year.value)}`.replace("\u06CC\u06A9 \u0647\u0632\u0627\u0631", "\u0647\u0632\u0627\u0631") : year.value;
1241
+ let formattedTime = "";
1242
+ if (showTime) {
1243
+ const timeOptions = {
1244
+ hour: "2-digit",
1245
+ minute: "2-digit",
1246
+ ...showSeconds && { second: "2-digit" },
1247
+ hour12: false,
1248
+ // Use 24-hour format
1249
+ localeMatcher: "best fit"
1250
+ };
1251
+ const t = new Intl.DateTimeFormat("fa-IR", timeOptions).format(date);
1252
+ formattedTime = ` ${separator} ${t}`;
1253
+ }
1254
+ return `${formattedDay} ${month.value} ${formattedYear}${formattedTime}`;
1255
+ } else return date;
1256
+ };
1257
+ var persianDateFormatter = new Intl.DateTimeFormat("en-US-u-ca-persian", {
1258
+ year: "numeric",
1259
+ month: "numeric",
1260
+ day: "numeric",
1261
+ timeZone: "UTC"
1262
+ });
1263
+ function getPersianYMD(date) {
1264
+ const parts = persianDateFormatter.formatToParts(date);
1265
+ const year = Number(parts.find((p) => p.type === "year")?.value);
1266
+ const month = Number(parts.find((p) => p.type === "month")?.value);
1267
+ const day = Number(parts.find((p) => p.type === "day")?.value);
1268
+ if (!year || !month || !day) throw new Error("Failed to parse Persian date");
1269
+ return { year, month, day };
1270
+ }
1271
+ function jalaliToDateUTC(jy, jm, jd) {
1272
+ const DAY_MS = 24 * 60 * 60 * 1e3;
1273
+ const approxYear = jy + 621;
1274
+ let lowDay = Math.floor(Date.UTC(approxYear - 2, 0, 1) / DAY_MS);
1275
+ let highDay = Math.floor(Date.UTC(approxYear + 2, 11, 31) / DAY_MS);
1276
+ while (lowDay <= highDay) {
1277
+ const midDay = Math.floor((lowDay + highDay) / 2);
1278
+ const midDate = new Date(midDay * DAY_MS);
1279
+ const { year, month, day } = getPersianYMD(midDate);
1280
+ if (year === jy && month === jm && day === jd) return midDate;
1281
+ const isBefore = year < jy || year === jy && month < jm || year === jy && month === jm && day < jd;
1282
+ if (isBefore) lowDay = midDay + 1;
1283
+ else highDay = midDay - 1;
1284
+ }
1285
+ throw new Error("Invalid Jalali date");
1286
+ }
1287
+
1288
+ // src/components/MobileDatePicker.tsx
1289
+ import { Fragment as Fragment3, jsx as jsx37, jsxs as jsxs3 } from "react/jsx-runtime";
1290
+ var MobileDatePicker = ({
1291
+ width = "100%",
1292
+ height = 48,
1293
+ label,
1294
+ value,
1295
+ onChange,
1296
+ disabled = false,
1297
+ error,
1298
+ helperText,
1299
+ textFieldSxProps,
1300
+ placeholder,
1301
+ minDate,
1302
+ maxDate
1303
+ }) => {
1304
+ const [dateValue, setDateValue] = useState(value && gregorianToJalali(value));
1305
+ const [selectedDate, setSelectedDate] = useState(null);
1306
+ const [isModalOpen, setIsModalOpen] = useState(false);
1307
+ const [defaultCalenderValue, setDefaultCalenderValue] = useState("");
1308
+ const calendarRef = useRef2(null);
1309
+ const openCalendar = () => {
1310
+ if (disabled) return;
1311
+ setIsModalOpen(true);
1312
+ };
1313
+ const closeCalendar = () => {
1314
+ setIsModalOpen(false);
1315
+ setSelectedDate(null);
1316
+ };
1317
+ const handleDateChange = (date) => {
1318
+ setSelectedDate(`${date.year}/${date.month}/${date.day}`);
1319
+ };
1320
+ const handleSubmit = () => {
1321
+ if (selectedDate) {
1322
+ setDateValue(selectedDate);
1323
+ onChange(jalaliToGregorian(selectedDate));
1324
+ }
1325
+ closeCalendar();
1326
+ };
1327
+ const handleCancel = () => {
1328
+ closeCalendar();
1329
+ };
1330
+ useEffect(() => {
1331
+ if (!value) {
1332
+ setDateValue("");
1333
+ setSelectedDate(null);
1334
+ }
1335
+ }, [value]);
1336
+ useEffect(() => {
1337
+ if (selectedDate || dateValue) {
1338
+ setDefaultCalenderValue(`${selectedDate || dateValue}`);
1339
+ } else {
1340
+ if (maxDate) {
1341
+ setDefaultCalenderValue(maxDate);
1342
+ } else {
1343
+ setDefaultCalenderValue("");
1344
+ }
1345
+ }
1346
+ }, [maxDate, selectedDate, dateValue]);
1347
+ const mergedSx = { width, ...textFieldSxProps };
1348
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
1349
+ /* @__PURE__ */ jsx37("style", { children: ` .rmdp-day.rmdp-today span {
1350
+ background-color: #ACEED6 !important;
1351
+ }
1352
+
1353
+ .rmdp-day span {
1354
+ border-radius: 6px !important;
1355
+ }
1356
+
1357
+ .rmdp-day.rmdp-selected span:not(.highlight) {
1358
+ background-color: #1DBF98 !important;
1359
+ box-shadow: 0 0 1px #8798ad;
1360
+ color: #fff;
1361
+ }
1362
+
1363
+ @media (max-height: 450px), (max-width: 450px) {
1364
+ .rmdp-day span {
1365
+ font-size: 14px !important;
1366
+ padding-left: 0.5px;
1367
+ }
1368
+ }
1369
+
1370
+ @media (max-height: 450px), (max-width: 450px) {
1371
+ .rmdp-header, .rmdp-month-name {
1372
+ font-size: 14px !important;
1373
+ }
1374
+ }
1375
+
1376
+ .rmdp-week-day {
1377
+ color: #1DBF98 !important;
1378
+ font-size: 14 !important;
1379
+ }
1380
+
1381
+ .rmdp-arrow {
1382
+ border: solid #1DBF98 !important;
1383
+ border-width: 0 2px 2px 0 !important;
1384
+ }
1385
+
1386
+ .rmdp-action-button {
1387
+ color: #1DBF98 !important;
1388
+ }
1389
+
1390
+ .rmdp-wrapper {
1391
+ border-radius: 12px !important;
1392
+ box-shadow: none !important;
1393
+ }
1394
+
1395
+ .rmdp-week,
1396
+ .rmdp-ym {
1397
+ display: flex;
1398
+ justify-content: space-between;
1399
+ gap: 10px !important;
1400
+ }
1401
+ .rmdp-day-picker {
1402
+ padding-top: 24px !important;
1403
+ }` }),
1404
+ /* @__PURE__ */ jsxs3(Modal_default, { open: isModalOpen, onClose: closeCalendar, children: [
1405
+ /* @__PURE__ */ jsx37(Box_default, { sx: { marginBottom: "20px" }, children: /* @__PURE__ */ jsx37(
1406
+ Calendar,
1407
+ {
1408
+ ref: calendarRef,
1409
+ monthYearSeparator: "|",
1410
+ calendar: persian,
1411
+ locale: persian_fa,
1412
+ value: defaultCalenderValue,
1413
+ onChange: handleDateChange,
1414
+ minDate,
1415
+ maxDate
1416
+ }
1417
+ ) }),
1418
+ /* @__PURE__ */ jsxs3(Box_default, { sx: { display: "flex", gap: 2, justifyContent: "end" }, children: [
1419
+ /* @__PURE__ */ jsx37(
1420
+ Button_default,
1421
+ {
1422
+ variant: "outlined",
1423
+ buttonSize: "XS",
1424
+ onClick: handleCancel,
1425
+ sx: {
1426
+ color: defaultColors.neutral.light,
1427
+ borderColor: defaultColors.neutral[300]
1428
+ },
1429
+ children: "\u0644\u063A\u0648"
1430
+ }
1431
+ ),
1432
+ /* @__PURE__ */ jsx37(Button_default, { variant: "contained", buttonSize: "XS", onClick: handleSubmit, children: "\u062A\u0627\u06CC\u06CC\u062F" })
1433
+ ] })
1434
+ ] }),
1435
+ /* @__PURE__ */ jsx37(
1436
+ TextField_default,
1437
+ {
1438
+ disabled,
1439
+ onClick: openCalendar,
1440
+ endAdornment: /* @__PURE__ */ jsx37(
1441
+ CalendarIcon,
1442
+ {
1443
+ color: disabled ? defaultColors.neutral[300] : defaultColors.neutral.dark,
1444
+ size: 20
1445
+ }
1446
+ ),
1447
+ slotProps: { input: { readOnly: true }, inputLabel: { shrink: true } },
1448
+ placeholder,
1449
+ value: dateValue,
1450
+ height,
1451
+ label,
1452
+ variant: "outlined",
1453
+ sx: mergedSx,
1454
+ error,
1455
+ helperText
1456
+ }
1457
+ )
1458
+ ] });
1459
+ };
1460
+ var MobileDatePicker_default = MobileDatePicker;
1461
+
1462
+ // src/components/Fab.tsx
1463
+ import { Fab as MuiFab } from "@mui/material";
1464
+ import { jsx as jsx38 } from "react/jsx-runtime";
1465
+ var Fab = ({ children, ...props }) => {
1466
+ return /* @__PURE__ */ jsx38(MuiFab, { ...props, children });
1467
+ };
1468
+ var Fab_default = Fab;
1469
+
1470
+ // src/components/Tab.tsx
1471
+ import { Fragment as Fragment4, useEffect as useEffect2, useState as useState2 } from "react";
1472
+ import { jsx as jsx39, jsxs as jsxs4 } from "react/jsx-runtime";
1473
+ var Tab = ({ tabs, onChange, activeTab, fontSize = 14 }) => {
1474
+ const [tabValue, setTabValue] = useState2(activeTab ? activeTab : "");
1475
+ useEffect2(() => {
1476
+ tabValue && onChange(tabValue);
1477
+ }, [tabValue]);
1478
+ return /* @__PURE__ */ jsx39(
1479
+ Box_default,
1480
+ {
1481
+ sx: {
1482
+ display: "flex",
1483
+ width: "100%",
1484
+ justifyContent: "space-between",
1485
+ alignItems: "end",
1486
+ bgcolor: "white",
1487
+ px: 2,
1488
+ borderRadius: 3,
1489
+ height: 48
1490
+ },
1491
+ children: tabs.map((tab, index) => /* @__PURE__ */ jsxs4(Fragment4, { children: [
1492
+ /* @__PURE__ */ jsx39(Box_default, { sx: { width: "100%" }, children: /* @__PURE__ */ jsx39(
1493
+ Typography_default,
1494
+ {
1495
+ onClick: () => {
1496
+ setTabValue(tab.value);
1497
+ },
1498
+ color: `${tab.value == tabValue ? "neutral.dark" : "neutral.light"}`,
1499
+ fontSize,
1500
+ fontWeight: `${tab.value == tabValue ? 700 : 500}`,
1501
+ sx: {
1502
+ p: 3.5,
1503
+ cursor: "pointer",
1504
+ textAlign: "center",
1505
+ position: "relative",
1506
+ WebkitTapHighlightColor: "transparent",
1507
+ "&:focus, &:active": {
1508
+ backgroundColor: "transparent",
1509
+ outline: "none"
1510
+ },
1511
+ "&::after": tab.value == tabValue ? {
1512
+ content: '""',
1513
+ position: "absolute",
1514
+ bottom: 0,
1515
+ left: "35%",
1516
+ right: "35%",
1517
+ borderBottom: "2px solid currentColor"
1518
+ } : {}
1519
+ },
1520
+ children: tab.label
1521
+ }
1522
+ ) }),
1523
+ index !== tabs.length - 1 && /* @__PURE__ */ jsx39(Divider_default, { sx: { my: 3 }, orientation: "vertical", flexItem: true })
1524
+ ] }, index))
1525
+ }
1526
+ );
1527
+ };
1528
+ var Tab_default = Tab;
1529
+
1530
+ // src/constants/stepConnectorClasses.ts
1531
+ import { stepConnectorClasses as MuiStepConnectorClasses } from "@mui/material";
1532
+
1533
+ // src/components/CounterBoxInput.tsx
1534
+ import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
1535
+ import { Add, Minus } from "iconsax-react";
1536
+ import { jsx as jsx40, jsxs as jsxs5 } from "react/jsx-runtime";
1537
+ function countDecimalDigits(num) {
1538
+ let str = num.toString();
1539
+ if (str.includes("e")) {
1540
+ const [, exponent] = str.split("e");
1541
+ const precision = Math.abs(parseInt(exponent));
1542
+ str = Number(num).toFixed(precision);
1543
+ }
1544
+ const parts = str.split(".");
1545
+ return parts[1] ? parts[1].length : 0;
1546
+ }
1547
+ var CounterBoxInput = ({
1548
+ min = 0,
1549
+ max = 1e5,
1550
+ mb = 0,
1551
+ error: propError = false,
1552
+ helperText: propHelperText = "",
1553
+ step = 1,
1554
+ fullWidth = false,
1555
+ unit = "\u0631\u06CC\u0627\u0644",
1556
+ iconColor = defaultColors.neutral.light,
1557
+ iconBackgroundColor = defaultColors.neutral[200],
1558
+ onChange,
1559
+ allowFloat = false,
1560
+ value: controlledValue = 0,
1561
+ maxAvailable,
1562
+ minErrText,
1563
+ disabledInput = false,
1564
+ maxErrText
1565
+ }) => {
1566
+ const fixRate = countDecimalDigits(step);
1567
+ const convertPersianToEnglish = (str) => str.replace(/[۰-۹]/g, (d) => String.fromCharCode(d.charCodeAt(0) - 1728));
1568
+ const formatNumber = (numStr) => {
1569
+ if (numStr === "" || isNaN(Number(numStr))) return numStr;
1570
+ return Number(numStr).toLocaleString("en-US");
1571
+ };
1572
+ const [draft, setDraft] = useState3(
1573
+ () => allowFloat ? String(controlledValue ?? 0) : (controlledValue ?? 0).toFixed(0)
1574
+ );
1575
+ useEffect3(() => {
1576
+ if (allowFloat) {
1577
+ const next = String(controlledValue ?? 0);
1578
+ const draftNum = Number(draft);
1579
+ const nextNum = Number(next);
1580
+ if (Number.isNaN(draftNum) || draftNum !== nextNum) setDraft(next);
1581
+ } else {
1582
+ setDraft((controlledValue ?? 0).toFixed(0));
1583
+ }
1584
+ }, [controlledValue, allowFloat]);
1585
+ const numericFromDraft = useMemo(() => {
1586
+ const raw = allowFloat ? draft : String(controlledValue ?? 0);
1587
+ const cleaned = raw.replace(/,/g, "");
1588
+ const n = Number(cleaned);
1589
+ return Number.isFinite(n) ? n : NaN;
1590
+ }, [draft, allowFloat, controlledValue]);
1591
+ const emitChangeFromString = (nextStr) => {
1592
+ const english = convertPersianToEnglish(nextStr);
1593
+ let cleaned;
1594
+ if (allowFloat) {
1595
+ cleaned = english.replace(/,/g, "").replace(/[^0-9.]/g, "");
1596
+ const parts = cleaned.split(".");
1597
+ if (parts.length > 2) cleaned = parts[0] + "." + parts.slice(1).join("");
1598
+ setDraft(cleaned);
1599
+ if (cleaned !== "" && cleaned !== "." && Number.isFinite(Number(cleaned))) {
1600
+ onChange(Number(cleaned));
1601
+ }
1602
+ } else {
1603
+ cleaned = english.replace(/,/g, "").replace(/[^0-9]/g, "");
1604
+ const n = cleaned === "" ? 0 : parseInt(cleaned, 10);
1605
+ onChange(n);
1606
+ }
1607
+ };
1608
+ const handleIncrement = () => {
1609
+ const base = Number.isFinite(numericFromDraft) ? numericFromDraft : Number(controlledValue) || 0;
1610
+ const next = allowFloat && fixRate ? parseFloat((base + step).toFixed(fixRate)) : base + step;
1611
+ onChange(next);
1612
+ if (allowFloat) setDraft(String(next));
1613
+ };
1614
+ const handleDecrement = () => {
1615
+ const base = Number.isFinite(numericFromDraft) ? numericFromDraft : Number(controlledValue) || 0;
1616
+ const next = allowFloat && fixRate ? parseFloat((base - step).toFixed(fixRate)) : base - step;
1617
+ onChange(next);
1618
+ if (allowFloat) setDraft(String(next));
1619
+ };
1620
+ const currentForBounds = Number.isFinite(numericFromDraft) ? numericFromDraft : Number(controlledValue) || 0;
1621
+ const disableInc = currentForBounds >= max || !!maxAvailable && currentForBounds >= maxAvailable;
1622
+ const disableDec = currentForBounds <= min;
1623
+ const autoErrorText = useMemo(() => {
1624
+ if (!Number.isFinite(currentForBounds)) return "";
1625
+ if (currentForBounds < min) {
1626
+ return minErrText ?? `\u062D\u062F\u0627\u0642\u0644 \u0645\u0642\u062F\u0627\u0631 ${min.toLocaleString()} ${unit}`;
1627
+ }
1628
+ if (currentForBounds > max) {
1629
+ return maxErrText ?? `\u062D\u062F\u0627\u06A9\u062B\u0631 \u0645\u0642\u062F\u0627\u0631 ${max.toLocaleString()} ${unit}`;
1630
+ }
1631
+ if (maxAvailable !== void 0 && currentForBounds > maxAvailable) {
1632
+ return maxErrText ?? `\u062D\u062F\u0627\u06A9\u062B\u0631 \u0645\u0648\u062C\u0648\u062F\u06CC ${maxAvailable.toLocaleString()} ${unit}`;
1633
+ }
1634
+ return "";
1635
+ }, [currentForBounds, min, max, maxAvailable, unit, minErrText, maxErrText]);
1636
+ const isEmptyOrZero = currentForBounds === 0 || draft === "" || draft === ".";
1637
+ const effectiveError = isEmptyOrZero ? false : propError || !!autoErrorText;
1638
+ const resolvedErrorText = autoErrorText || propHelperText;
1639
+ const effectiveHelper = isEmptyOrZero ? propHelperText : effectiveError ? resolvedErrorText : propHelperText;
1640
+ const displayValue = allowFloat ? draft : formatNumber((controlledValue ?? 0).toFixed(0));
1641
+ return /* @__PURE__ */ jsx40(
1642
+ TextField_default,
1643
+ {
1644
+ dir: "ltr",
1645
+ type: "text",
1646
+ height: 48,
1647
+ value: displayValue,
1648
+ error: effectiveError,
1649
+ fullWidth,
1650
+ helperText: !isEmptyOrZero && effectiveHelper,
1651
+ disabled: disabledInput,
1652
+ onChange: (e) => emitChangeFromString(e.target.value),
1653
+ inputProps: {
1654
+ inputMode: "decimal",
1655
+ pattern: allowFloat ? "[0-9.]*" : "[0-9]*"
1656
+ },
1657
+ sx: {
1658
+ mb: effectiveHelper ? mb : 0,
1659
+ "& .MuiInputBase-input": { textAlign: "center" },
1660
+ "& .MuiInputBase-root.MuiOutlinedInput-root": {
1661
+ px: 0,
1662
+ "&.Mui-disabled": {
1663
+ "& .MuiInputBase-input": {
1664
+ WebkitTextFillColor: defaultColors.neutral.main
1665
+ }
1666
+ }
1667
+ },
1668
+ "&.MuiFormControl-root.MuiTextField-root .MuiFormHelperText-root": {
1669
+ textAlign: "center",
1670
+ "&.Mui-disabled": {
1671
+ color: propError ? defaultColors.red.main : defaultColors.neutral.main
1672
+ }
1673
+ }
1674
+ },
1675
+ endAdornment: /* @__PURE__ */ jsx40(
1676
+ IconButton_default,
1677
+ {
1678
+ sx: {
1679
+ width: 32,
1680
+ height: 32,
1681
+ bgcolor: iconBackgroundColor,
1682
+ p: 1,
1683
+ borderRadius: 2,
1684
+ color: iconColor,
1685
+ "&.Mui-disabled": {
1686
+ color: defaultColors.neutral.light,
1687
+ bgcolor: defaultColors.neutral[200]
1688
+ }
1689
+ },
1690
+ onClick: handleIncrement,
1691
+ disabled: disableInc,
1692
+ children: /* @__PURE__ */ jsx40(
1693
+ Add,
1694
+ {
1695
+ size: 22,
1696
+ color: disableInc ? defaultColors.neutral.light : iconColor
1697
+ }
1698
+ )
1699
+ }
1700
+ ),
1701
+ startAdornment: /* @__PURE__ */ jsxs5(
1702
+ Box_default,
1703
+ {
1704
+ sx: {
1705
+ display: "flex",
1706
+ justifyContent: "center",
1707
+ alignItems: "center",
1708
+ gap: 3
1709
+ },
1710
+ children: [
1711
+ /* @__PURE__ */ jsx40(
1712
+ IconButton_default,
1713
+ {
1714
+ sx: {
1715
+ width: 32,
1716
+ height: 32,
1717
+ bgcolor: iconBackgroundColor,
1718
+ p: 1,
1719
+ borderRadius: 2,
1720
+ color: iconColor,
1721
+ "&.Mui-disabled": {
1722
+ color: defaultColors.neutral.light,
1723
+ bgcolor: defaultColors.neutral[200]
1724
+ }
1725
+ },
1726
+ onClick: handleDecrement,
1727
+ disabled: disableDec,
1728
+ children: /* @__PURE__ */ jsx40(
1729
+ Minus,
1730
+ {
1731
+ size: 16,
1732
+ color: disableDec ? defaultColors.neutral.light : iconColor
1733
+ }
1734
+ )
1735
+ }
1736
+ ),
1737
+ /* @__PURE__ */ jsx40(Typography_default, { variant: "body2", color: "neutral.main", children: unit })
1738
+ ]
1739
+ }
1740
+ )
1741
+ }
1742
+ );
1743
+ };
1744
+ var CounterBoxInput_default = CounterBoxInput;
1745
+
1746
+ // src/components/SvgIcon.tsx
1747
+ import { jsx as jsx41 } from "react/jsx-runtime";
1748
+ var SvgIcon = ({
1749
+ src,
1750
+ color = "black",
1751
+ size = 24
1752
+ }) => {
1753
+ const style = {
1754
+ width: size,
1755
+ height: size,
1756
+ backgroundColor: color,
1757
+ maskImage: `url(${src})`,
1758
+ WebkitMaskImage: `url(${src})`,
1759
+ maskRepeat: "no-repeat",
1760
+ WebkitMaskRepeat: "no-repeat",
1761
+ maskSize: "contain",
1762
+ WebkitMaskSize: "contain",
1763
+ maskPosition: "center",
1764
+ WebkitMaskPosition: "center"
1765
+ };
1766
+ return /* @__PURE__ */ jsx41("div", { style });
1767
+ };
1768
+ var SvgIcon_default = SvgIcon;
1769
+
1770
+ // src/components/Dialog.tsx
1771
+ import { Dialog as MuiDialog } from "@mui/material";
1772
+ import { jsx as jsx42 } from "react/jsx-runtime";
1773
+ var Dialog2 = ({ children, ...props }) => {
1774
+ return /* @__PURE__ */ jsx42(MuiDialog, { ...props, children });
1775
+ };
1776
+ var Dialog_default = Dialog2;
1777
+
1778
+ // src/components/LoadingModal.tsx
1779
+ import { Typography as Typography3 } from "@mui/material";
1780
+ import { jsx as jsx43, jsxs as jsxs6 } from "react/jsx-runtime";
1781
+ var LoadingModal = ({ isOpen }) => {
1782
+ return /* @__PURE__ */ jsx43(Modal_default, { open: isOpen, children: /* @__PURE__ */ jsxs6(
1783
+ Box_default,
1784
+ {
1785
+ sx: {
1786
+ display: "flex",
1787
+ flexDirection: "column",
1788
+ alignItems: "center",
1789
+ gap: 4,
1790
+ width: "150px"
1791
+ },
1792
+ children: [
1793
+ /* @__PURE__ */ jsx43(Loading_default, { size: 40 }),
1794
+ /* @__PURE__ */ jsx43(Typography3, { children: "\u0686\u0646\u062F \u0644\u062D\u0638\u0647 \u0635\u0628\u0631 \u06A9\u0646 ..." })
1795
+ ]
1796
+ }
1797
+ ) });
1798
+ };
1799
+ var LoadingModal_default = LoadingModal;
1800
+
1801
+ // src/components/Image.tsx
1802
+ import { jsx as jsx44 } from "react/jsx-runtime";
1803
+ var Image = ({
1804
+ src,
1805
+ alt = "",
1806
+ width,
1807
+ height,
1808
+ objectFit = "cover",
1809
+ style = {},
1810
+ fallbackSrc,
1811
+ ...props
1812
+ }) => {
1813
+ const combinedStyle = {
1814
+ width,
1815
+ height,
1816
+ objectFit,
1817
+ ...style
1818
+ };
1819
+ return /* @__PURE__ */ jsx44("img", { src, alt, style: combinedStyle, loading: "lazy", ...props });
1820
+ };
1821
+ var Image_default = Image;
1822
+
1823
+ // src/components/Pagination.tsx
1824
+ import { Pagination as MuiPagination } from "@mui/material";
1825
+ import { jsx as jsx45 } from "react/jsx-runtime";
1826
+ var Pagination = ({ ...props }) => {
1827
+ return /* @__PURE__ */ jsx45(MuiPagination, { ...props });
1828
+ };
1829
+ var Pagination_default = Pagination;
1830
+
1831
+ // src/components/CircularProgress.tsx
1832
+ import { CircularProgress as MuiCircularProgress } from "@mui/material";
1833
+ import { jsx as jsx46 } from "react/jsx-runtime";
1834
+ var CircularProgress3 = ({ ...props }) => {
1835
+ return /* @__PURE__ */ jsx46(MuiCircularProgress, { ...props });
1836
+ };
1837
+ var CircularProgress_default = CircularProgress3;
1838
+
1839
+ // src/components/IosHiddenOtpInput.tsx
1840
+ import { useEffect as useEffect4 } from "react";
1841
+ import { jsx as jsx47 } from "react/jsx-runtime";
1842
+ var IosHiddenOtpInput = ({ onOtpChange }) => {
1843
+ useEffect4(() => {
1844
+ const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
1845
+ if (isIOS) {
1846
+ document.getElementById("ios-one-time-code")?.focus();
1847
+ }
1848
+ }, []);
1849
+ const normalize = (raw) => {
1850
+ const v = (raw || "").replace(/[^\d\u06F0-\u06F9\u0660-\u0669]/g, "");
1851
+ const normalized = v.replace(/[\u06F0-\u06F9]/g, (d) => String(d.charCodeAt(0) - 1776)).replace(/[\u0660-\u0669]/g, (d) => String(d.charCodeAt(0) - 1632)).slice(0, length);
1852
+ return normalized;
1853
+ };
1854
+ return /* @__PURE__ */ jsx47(
1855
+ "input",
1856
+ {
1857
+ id: "ios-one-time-code",
1858
+ name: "one-time-code",
1859
+ type: "text",
1860
+ inputMode: "numeric",
1861
+ autoComplete: "one-time-code",
1862
+ style: {
1863
+ position: "absolute",
1864
+ top: "-9999px",
1865
+ width: "1px",
1866
+ height: "1px",
1867
+ opacity: 0
1868
+ },
1869
+ onChange: (e) => {
1870
+ const otp = normalize(e.currentTarget.value);
1871
+ onOtpChange(otp);
1872
+ }
1873
+ }
1874
+ );
1875
+ };
1876
+ var IosHiddenOtpInput_default = IosHiddenOtpInput;
1877
+
1878
+ // src/components/CardNumberInput.tsx
1879
+ import { useState as useState4, useEffect as useEffect5 } from "react";
1880
+ import { Add as Add2 } from "iconsax-react";
1881
+
1882
+ // src/utils/toLatinDigit.ts
1883
+ var toLatinDigits = (input) => {
1884
+ if (!input) return "";
1885
+ const s = String(input);
1886
+ return s.replace(/[\u06F0-\u06F9]/g, (d) => String(d.charCodeAt(0) - 1776)).replace(/[\u0660-\u0669]/g, (d) => String(d.charCodeAt(0) - 1632));
1887
+ };
1888
+
1889
+ // src/components/CardNumberInput.tsx
1890
+ import { jsx as jsx48 } from "react/jsx-runtime";
1891
+ var getPanNumber = (pan) => {
1892
+ const latin = toLatinDigits(pan);
1893
+ return latin.replace(/\D/g, "").trim();
1894
+ };
1895
+ var formatCardNumber = (value) => {
1896
+ const latin = toLatinDigits(value);
1897
+ const cleaned = latin.replace(/\D/g, "");
1898
+ return cleaned.replace(/(\d{4})/g, "$1-").replace(/-$/, "").substring(0, 19);
1899
+ };
1900
+ var handleBeforeInput = (e) => {
1901
+ const data = e.data;
1902
+ if (data && !/^[0-9\u06F0-\u06F9\u0660-\u0669]+$/.test(data)) {
1903
+ e.preventDefault();
1904
+ }
1905
+ };
1906
+ var CardNumberInput = ({
1907
+ value,
1908
+ onChange,
1909
+ error = false,
1910
+ helperText = "",
1911
+ hasClearButton,
1912
+ onReset,
1913
+ bankLogo
1914
+ }) => {
1915
+ const [displayValue, setDisplayValue] = useState4("");
1916
+ useEffect5(() => {
1917
+ if (value) {
1918
+ setDisplayValue(formatCardNumber(value));
1919
+ } else {
1920
+ setDisplayValue("");
1921
+ }
1922
+ }, [value]);
1923
+ return /* @__PURE__ */ jsx48(
1924
+ TextField_default,
1925
+ {
1926
+ value: displayValue,
1927
+ label: "\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A",
1928
+ placeholder: "\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A",
1929
+ variant: "outlined",
1930
+ fullWidth: true,
1931
+ type: "text",
1932
+ error,
1933
+ helperText,
1934
+ inputProps: {
1935
+ inputMode: "numeric",
1936
+ autoComplete: "tel",
1937
+ onBeforeInput: handleBeforeInput
1938
+ },
1939
+ startAdornment: bankLogo ? /* @__PURE__ */ jsx48(Box_default, { display: "flex", alignItems: "center", gap: "8px", children: /* @__PURE__ */ jsx48(Image_default, { src: bankLogo, alt: "Bank Logo", width: 20, height: 20 }) }) : void 0,
1940
+ endAdornment: hasClearButton ? /* @__PURE__ */ jsx48(
1941
+ IconButton_default,
1942
+ {
1943
+ onClick: () => {
1944
+ if (onReset) onReset();
1945
+ },
1946
+ children: /* @__PURE__ */ jsx48(
1947
+ Add2,
1948
+ {
1949
+ size: "24",
1950
+ color: defaultColors.neutral[500],
1951
+ style: { transform: "rotate(45deg)" }
1952
+ }
1953
+ )
1954
+ }
1955
+ ) : void 0,
1956
+ onChange: (e) => {
1957
+ const formatted = formatCardNumber(e.target.value);
1958
+ setDisplayValue(formatted);
1959
+ const cleaned = getPanNumber(formatted);
1960
+ onChange(cleaned);
1961
+ }
1962
+ }
1963
+ );
1964
+ };
1965
+ var CardNumberInput_default = CardNumberInput;
1966
+
1967
+ // src/components/NumberInput.tsx
1968
+ import { useState as useState5, useEffect as useEffect6 } from "react";
1969
+ import { Add as Add3 } from "iconsax-react";
1970
+ import { jsx as jsx49, jsxs as jsxs7 } from "react/jsx-runtime";
1971
+ var getCleanNumber = (value, fungible = false) => {
1972
+ const latin = toLatinDigits(value);
1973
+ if (fungible) {
1974
+ if (latin === ".") {
1975
+ return ".";
1976
+ }
1977
+ const endsWithDot = latin.endsWith(".") && latin.length > 1;
1978
+ const parts = latin.split(".");
1979
+ if (parts.length > 2) {
1980
+ const integerPart2 = parts[0].replace(/\D/g, "");
1981
+ const decimalPart2 = parts.slice(1).join("").replace(/\D/g, "");
1982
+ return integerPart2 + (decimalPart2 ? "." + decimalPart2 : endsWithDot ? "." : "");
1983
+ }
1984
+ const integerPart = parts[0].replace(/\D/g, "");
1985
+ const decimalPart = parts[1]?.replace(/\D/g, "") || "";
1986
+ const startsWithDot = latin.startsWith(".");
1987
+ if (startsWithDot && !integerPart && decimalPart) {
1988
+ return "0." + decimalPart;
1989
+ }
1990
+ if (startsWithDot && !integerPart && !decimalPart) {
1991
+ return ".";
1992
+ }
1993
+ if (endsWithDot && !decimalPart && integerPart) {
1994
+ return integerPart + ".";
1995
+ }
1996
+ if (decimalPart) {
1997
+ return integerPart + "." + decimalPart;
1998
+ }
1999
+ return integerPart;
2000
+ }
2001
+ return latin.replace(/\D/g, "").trim();
2002
+ };
2003
+ var formatWithSeparator = (value) => {
2004
+ if (!value) return "";
2005
+ const parts = value.split(".");
2006
+ const integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
2007
+ return parts.length > 1 ? integerPart + "." + parts[1] : integerPart;
2008
+ };
2009
+ var handleBeforeInput2 = (e, fungible) => {
2010
+ const data = e.data;
2011
+ if (fungible) {
2012
+ if (data && !/^[0-9.\u06F0-\u06F9\u0660-\u0669]+$/.test(data)) {
2013
+ e.preventDefault();
2014
+ }
2015
+ } else {
2016
+ if (data && !/^[0-9\u06F0-\u06F9\u0660-\u0669]+$/.test(data)) {
2017
+ e.preventDefault();
2018
+ }
2019
+ }
2020
+ };
2021
+ var handleKeyDown = (e, fungible, currentValue) => {
2022
+ if (fungible) {
2023
+ if (e.key === "." || e.key === ",") {
2024
+ if (currentValue.includes(".")) {
2025
+ e.preventDefault();
2026
+ }
2027
+ return;
2028
+ }
2029
+ if (!/^[0-9\u06F0-\u06F9\u0660-\u0669]$/.test(e.key) && ![
2030
+ "Backspace",
2031
+ "Delete",
2032
+ "ArrowLeft",
2033
+ "ArrowRight",
2034
+ "Tab",
2035
+ "Enter",
2036
+ "Home",
2037
+ "End"
2038
+ ].includes(e.key) && !(e.ctrlKey || e.metaKey)) {
2039
+ e.preventDefault();
2040
+ }
2041
+ } else {
2042
+ if (!/^[0-9\u06F0-\u06F9\u0660-\u0669]$/.test(e.key) && ![
2043
+ "Backspace",
2044
+ "Delete",
2045
+ "ArrowLeft",
2046
+ "ArrowRight",
2047
+ "Tab",
2048
+ "Enter",
2049
+ "Home",
2050
+ "End"
2051
+ ].includes(e.key) && !(e.ctrlKey || e.metaKey)) {
2052
+ e.preventDefault();
2053
+ }
2054
+ }
2055
+ };
2056
+ var NumberInput = ({
2057
+ value,
2058
+ onChange,
2059
+ error = false,
2060
+ helperText = "",
2061
+ hasClearButton,
2062
+ onReset,
2063
+ label = "\u0634\u0645\u0627\u0631\u0647",
2064
+ placeholder = "\u0634\u0645\u0627\u0631\u0647 \u0631\u0627 \u0648\u0627\u0631\u062F \u06A9\u0646\u06CC\u062F",
2065
+ fungible = false,
2066
+ disabled = false,
2067
+ maxLength,
2068
+ minLength,
2069
+ unit
2070
+ }) => {
2071
+ const [displayValue, setDisplayValue] = useState5("");
2072
+ useEffect6(() => {
2073
+ if (value) {
2074
+ if (fungible) {
2075
+ setDisplayValue(value);
2076
+ } else {
2077
+ setDisplayValue(formatWithSeparator(value));
2078
+ }
2079
+ } else {
2080
+ setDisplayValue("");
2081
+ }
2082
+ }, [value, fungible]);
2083
+ return /* @__PURE__ */ jsx49(
2084
+ TextField_default,
2085
+ {
2086
+ value: displayValue,
2087
+ label,
2088
+ placeholder,
2089
+ variant: "outlined",
2090
+ fullWidth: true,
2091
+ type: "text",
2092
+ error,
2093
+ disabled,
2094
+ helperText,
2095
+ inputProps: {
2096
+ inputMode: fungible ? "decimal" : "numeric",
2097
+ maxLength,
2098
+ minLength,
2099
+ autoComplete: "off",
2100
+ onBeforeInput: (e) => handleBeforeInput2(e, fungible),
2101
+ onKeyDown: (e) => handleKeyDown(e, fungible, displayValue)
2102
+ },
2103
+ endAdornment: hasClearButton || unit ? /* @__PURE__ */ jsxs7(
2104
+ Box_default,
2105
+ {
2106
+ sx: {
2107
+ display: "flex",
2108
+ alignItems: "center",
2109
+ gap: 2,
2110
+ justifyContent: "end"
2111
+ },
2112
+ children: [
2113
+ unit && /* @__PURE__ */ jsx49(Typography_default, { variant: "body1", color: "neutral.light", children: unit }),
2114
+ hasClearButton && /* @__PURE__ */ jsx49(
2115
+ IconButton_default,
2116
+ {
2117
+ onClick: () => {
2118
+ if (onReset) onReset();
2119
+ },
2120
+ children: /* @__PURE__ */ jsx49(
2121
+ Add3,
2122
+ {
2123
+ size: "24",
2124
+ color: defaultColors.neutral[500],
2125
+ style: { transform: "rotate(45deg)" }
2126
+ }
2127
+ )
2128
+ }
2129
+ )
2130
+ ]
2131
+ }
2132
+ ) : void 0,
2133
+ onChange: (e) => {
2134
+ const inputValue = e.target.value;
2135
+ if (fungible) {
2136
+ const cleaned = getCleanNumber(inputValue, fungible);
2137
+ setDisplayValue(cleaned);
2138
+ onChange(cleaned);
2139
+ } else {
2140
+ const cleaned = getCleanNumber(inputValue, fungible);
2141
+ setDisplayValue(formatWithSeparator(cleaned));
2142
+ onChange(cleaned);
2143
+ }
2144
+ },
2145
+ sx: {
2146
+ "& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button": {
2147
+ display: "none"
2148
+ },
2149
+ "& input[type=number]": {
2150
+ MozAppearance: "textfield"
2151
+ }
2152
+ }
2153
+ }
2154
+ );
2155
+ };
2156
+ var NumberInput_default = NumberInput;
2157
+
2158
+ // src/components/InputPhoneNumber.tsx
2159
+ import { jsx as jsx50 } from "react/jsx-runtime";
2160
+ var normalizeDigits2 = (s) => s.replace(/[\u06F0-\u06F9]/g, (d) => String(d.charCodeAt(0) - 1776)).replace(/[\u0660-\u0669]/g, (d) => String(d.charCodeAt(0) - 1632));
2161
+ var asciiDigitsOnly = (s) => normalizeDigits2(s).replace(/\D/g, "");
2162
+ var normalizeIranPhone = (s, maxDigitLength = 11) => {
2163
+ const normalized = normalizeDigits2(s).trim();
2164
+ let cleaned = normalized.replace(/[^\d+]/g, "");
2165
+ const hasPlus = cleaned.startsWith("+");
2166
+ cleaned = cleaned.replace(/\+/g, "");
2167
+ let digits = cleaned;
2168
+ if (hasPlus && digits.startsWith("98")) {
2169
+ digits = "0" + digits.slice(2);
2170
+ }
2171
+ if (digits.startsWith("0098")) {
2172
+ digits = "0" + digits.slice(4);
2173
+ }
2174
+ if (digits.startsWith("98")) {
2175
+ digits = "0" + digits.slice(2);
2176
+ }
2177
+ if (digits.length === 10 && digits.startsWith("9")) {
2178
+ digits = "0" + digits;
2179
+ }
2180
+ return digits.slice(0, maxDigitLength);
2181
+ };
2182
+ var ALLOWED_INPUT = /^[0-9\u06F0-\u06F9\u0660-\u0669+\s]+$/;
2183
+ var InputPhoneNumber = ({
2184
+ value,
2185
+ onChange,
2186
+ onBlur,
2187
+ maxDigitLength = 11,
2188
+ inputRef,
2189
+ ref,
2190
+ inputProps: inputPropsProp,
2191
+ dir = "rtl",
2192
+ ...textFieldProps
2193
+ }) => {
2194
+ const refToUse = inputRef ?? ref;
2195
+ const handleBeforeInput3 = (e) => {
2196
+ const inputEvent = e.nativeEvent;
2197
+ const data = inputEvent.data;
2198
+ if (inputEvent.inputType === "insertFromPaste") return;
2199
+ if (data && !ALLOWED_INPUT.test(data)) {
2200
+ e.preventDefault();
2201
+ return;
2202
+ }
2203
+ if (data === "+") {
2204
+ const el = e.currentTarget;
2205
+ const nextValue = el.value.slice(0, el.selectionStart ?? el.value.length) + "+" + el.value.slice(el.selectionEnd ?? el.value.length);
2206
+ if (!nextValue.startsWith("+")) {
2207
+ e.preventDefault();
2208
+ }
2209
+ }
2210
+ };
2211
+ const handlePaste = (e) => {
2212
+ const pastedData = e.clipboardData.getData("text");
2213
+ const sanitized = normalizeIranPhone(pastedData, maxDigitLength);
2214
+ if (sanitized) {
2215
+ e.preventDefault();
2216
+ onChange(sanitized);
2217
+ }
2218
+ };
2219
+ const handleInput = (e) => {
2220
+ const input = e.currentTarget;
2221
+ let rawValue = input.value;
2222
+ const inputEvent = e.nativeEvent;
2223
+ const isAutofill = !inputEvent.inputType || inputEvent.inputType === "insertReplacementText";
2224
+ if (isAutofill && rawValue.length > 5) {
2225
+ const digitsOnly = asciiDigitsOnly(rawValue);
2226
+ if (digitsOnly.length > 5 && !digitsOnly.startsWith("0") && digitsOnly.endsWith("0")) {
2227
+ rawValue = digitsOnly.split("").reverse().join("");
2228
+ }
2229
+ }
2230
+ const sanitized = normalizeIranPhone(rawValue, maxDigitLength);
2231
+ if (value !== sanitized) {
2232
+ onChange(sanitized);
2233
+ }
2234
+ };
2235
+ return /* @__PURE__ */ jsx50(
2236
+ TextField_default,
2237
+ {
2238
+ ...textFieldProps,
2239
+ type: "tel",
2240
+ value,
2241
+ onChange: (e) => onChange(normalizeIranPhone(e.target.value, maxDigitLength)),
2242
+ onBlur,
2243
+ inputRef: refToUse,
2244
+ inputProps: {
2245
+ inputMode: "numeric",
2246
+ // Allow "+" in pattern so mobile keyboards don't fight the user.
2247
+ pattern: "[0-9\\u06F0-\\u06F9\\u0660-\\u0669+]*",
2248
+ autoComplete: "tel",
2249
+ dir,
2250
+ maxLength: Math.max(maxDigitLength + 4, 15),
2251
+ onBeforeInput: handleBeforeInput3,
2252
+ onInput: handleInput,
2253
+ onPaste: handlePaste,
2254
+ ...inputPropsProp
2255
+ }
2256
+ }
2257
+ );
2258
+ };
2259
+ var InputPhoneNumber_default = InputPhoneNumber;
2260
+
2261
+ // src/components/WheelDatePicker.tsx
2262
+ import {
2263
+ useEffect as useEffect7,
2264
+ useLayoutEffect,
2265
+ useMemo as useMemo2,
2266
+ useRef as useRef3,
2267
+ useState as useState6
2268
+ } from "react";
2269
+ import { flushSync } from "react-dom";
2270
+ import { Add as Add4 } from "iconsax-react";
2271
+ import { Calendar as Calendar2 } from "iconsax-react";
2272
+ import { jsx as jsx51, jsxs as jsxs8 } from "react/jsx-runtime";
2273
+ var PERSIAN_MONTHS = [
2274
+ { value: 1, label: "\u0641\u0631\u0648\u0631\u062F\u06CC\u0646" },
2275
+ { value: 2, label: "\u0627\u0631\u062F\u06CC\u0628\u0647\u0634\u062A" },
2276
+ { value: 3, label: "\u062E\u0631\u062F\u0627\u062F" },
2277
+ { value: 4, label: "\u062A\u06CC\u0631" },
2278
+ { value: 5, label: "\u0645\u0631\u062F\u0627\u062F" },
2279
+ { value: 6, label: "\u0634\u0647\u0631\u06CC\u0648\u0631" },
2280
+ { value: 7, label: "\u0645\u0647\u0631" },
2281
+ { value: 8, label: "\u0622\u0628\u0627\u0646" },
2282
+ { value: 9, label: "\u0622\u0630\u0631" },
2283
+ { value: 10, label: "\u062F\u06CC" },
2284
+ { value: 11, label: "\u0628\u0647\u0645\u0646" },
2285
+ { value: 12, label: "\u0627\u0633\u0641\u0646\u062F" }
2286
+ ];
2287
+ function isJalaliLeapYear(jy) {
2288
+ return (jy + 38) * 31 % 128 < 31;
2289
+ }
2290
+ function getDaysInJalaliMonth(jy, jm) {
2291
+ if (jm <= 6) return 31;
2292
+ if (jm <= 11) return 30;
2293
+ return isJalaliLeapYear(jy) ? 30 : 29;
2294
+ }
2295
+ var ITEM_HEIGHT = 44;
2296
+ var WHEEL_VISIBLE_ITEMS = 3;
2297
+ var TOTAL_VIRTUAL_SLOTS = 10001;
2298
+ var MIDDLE_SLOT_INDEX = Math.floor(TOTAL_VIRTUAL_SLOTS / 2);
2299
+ var VISIBLE_WINDOW_BUFFER = 8;
2300
+ var SCROLL_END_DEBOUNCE_MS = 120;
2301
+ var TOP_PADDING = ITEM_HEIGHT * (WHEEL_VISIBLE_ITEMS - 1) / 2;
2302
+ var SELECTED_ROW_INDEX = 1;
2303
+ var REST_SCROLL_TOP = TOP_PADDING + (MIDDLE_SLOT_INDEX - SELECTED_ROW_INDEX) * ITEM_HEIGHT;
2304
+ function mod(a, n) {
2305
+ if (n <= 0) return 0;
2306
+ return (a % n + n) % n;
2307
+ }
2308
+ function clampIndex(index, n) {
2309
+ return Math.max(0, Math.min(n - 1, index));
2310
+ }
2311
+ function FlatWheelColumn({
2312
+ items,
2313
+ value,
2314
+ getKey,
2315
+ getLabel,
2316
+ onSelect,
2317
+ wrap = true
2318
+ }) {
2319
+ const scrollRef = useRef3(null);
2320
+ const isProgrammaticScrollRef = useRef3(false);
2321
+ const scrollEndTimeoutRef = useRef3(
2322
+ null
2323
+ );
2324
+ const valueIndex = useMemo2(
2325
+ () => items.findIndex((i) => getKey(i) === getKey(value)),
2326
+ [items, value, getKey]
2327
+ );
2328
+ const safeValueIndex = valueIndex >= 0 ? valueIndex : 0;
2329
+ const N = items.length;
2330
+ const [currentIndex, setCurrentIndex] = useState6(safeValueIndex);
2331
+ const currentIndexRef = useRef3(currentIndex);
2332
+ currentIndexRef.current = currentIndex;
2333
+ useEffect7(() => {
2334
+ if (valueIndex >= 0 && valueIndex < N) {
2335
+ setCurrentIndex(valueIndex);
2336
+ } else if (N > 0) {
2337
+ setCurrentIndex(0);
2338
+ }
2339
+ }, [valueIndex, N]);
2340
+ const baseIndex = useMemo2(
2341
+ () => N > 0 ? mod(currentIndex - MIDDLE_SLOT_INDEX % N, N) : 0,
2342
+ [currentIndex, N]
2343
+ );
2344
+ const contentHeight = wrap ? TOP_PADDING + TOTAL_VIRTUAL_SLOTS * ITEM_HEIGHT + TOP_PADDING : TOP_PADDING + N * ITEM_HEIGHT + TOP_PADDING;
2345
+ const columnHeight = ITEM_HEIGHT * WHEEL_VISIBLE_ITEMS;
2346
+ const maxScrollLinear = Math.max(0, contentHeight - columnHeight);
2347
+ const restScrollTop = wrap ? REST_SCROLL_TOP : Math.min(
2348
+ maxScrollLinear,
2349
+ Math.max(
2350
+ 0,
2351
+ TOP_PADDING + (currentIndex - SELECTED_ROW_INDEX) * ITEM_HEIGHT
2352
+ )
2353
+ );
2354
+ const windowStart = wrap ? Math.max(0, MIDDLE_SLOT_INDEX - VISIBLE_WINDOW_BUFFER) : Math.max(
2355
+ 0,
2356
+ Math.floor((restScrollTop - TOP_PADDING) / ITEM_HEIGHT) - VISIBLE_WINDOW_BUFFER
2357
+ );
2358
+ const windowEnd = wrap ? Math.min(
2359
+ TOTAL_VIRTUAL_SLOTS - 1,
2360
+ MIDDLE_SLOT_INDEX + WHEEL_VISIBLE_ITEMS + VISIBLE_WINDOW_BUFFER
2361
+ ) : Math.min(
2362
+ N - 1,
2363
+ windowStart + WHEEL_VISIBLE_ITEMS + 2 * VISIBLE_WINDOW_BUFFER
2364
+ );
2365
+ const visibleItemCount = Math.max(0, windowEnd - windowStart + 1);
2366
+ const hasInitializedScroll = useRef3(false);
2367
+ useLayoutEffect(() => {
2368
+ const el = scrollRef.current;
2369
+ if (!el || N === 0 || hasInitializedScroll.current) return;
2370
+ hasInitializedScroll.current = true;
2371
+ isProgrammaticScrollRef.current = true;
2372
+ const initialTop = wrap ? REST_SCROLL_TOP : Math.min(
2373
+ maxScrollLinear,
2374
+ Math.max(
2375
+ 0,
2376
+ TOP_PADDING + (safeValueIndex - SELECTED_ROW_INDEX) * ITEM_HEIGHT
2377
+ )
2378
+ );
2379
+ el.scrollTop = initialTop;
2380
+ }, [N, wrap, safeValueIndex, maxScrollLinear]);
2381
+ const applyScrollDeltaAndSnap = () => {
2382
+ const el = scrollRef.current;
2383
+ if (!el || N === 0) return;
2384
+ const targetScrollTop = wrap ? REST_SCROLL_TOP : TOP_PADDING + (currentIndexRef.current - SELECTED_ROW_INDEX) * ITEM_HEIGHT;
2385
+ const scrollTop = el.scrollTop;
2386
+ const deltaItems = Math.round((scrollTop - targetScrollTop) / ITEM_HEIGHT);
2387
+ if (deltaItems === 0) return;
2388
+ const latestIndex = currentIndexRef.current;
2389
+ const newIndex = wrap ? mod(latestIndex + deltaItems, N) : clampIndex(latestIndex + deltaItems, N);
2390
+ flushSync(() => {
2391
+ setCurrentIndex(newIndex);
2392
+ });
2393
+ onSelect(items[newIndex]);
2394
+ isProgrammaticScrollRef.current = true;
2395
+ const targetTop = wrap ? REST_SCROLL_TOP : Math.min(
2396
+ maxScrollLinear,
2397
+ Math.max(
2398
+ 0,
2399
+ TOP_PADDING + (newIndex - SELECTED_ROW_INDEX) * ITEM_HEIGHT
2400
+ )
2401
+ );
2402
+ el.scrollTop = targetTop;
2403
+ };
2404
+ const handleScroll = () => {
2405
+ if (isProgrammaticScrollRef.current) {
2406
+ isProgrammaticScrollRef.current = false;
2407
+ return;
2408
+ }
2409
+ if (scrollEndTimeoutRef.current) clearTimeout(scrollEndTimeoutRef.current);
2410
+ scrollEndTimeoutRef.current = setTimeout(() => {
2411
+ scrollEndTimeoutRef.current = null;
2412
+ applyScrollDeltaAndSnap();
2413
+ }, SCROLL_END_DEBOUNCE_MS);
2414
+ };
2415
+ return /* @__PURE__ */ jsxs8(
2416
+ Box_default,
2417
+ {
2418
+ sx: {
2419
+ flex: 1,
2420
+ minWidth: 0,
2421
+ position: "relative",
2422
+ height: columnHeight
2423
+ },
2424
+ children: [
2425
+ /* @__PURE__ */ jsx51(
2426
+ Box_default,
2427
+ {
2428
+ ref: scrollRef,
2429
+ onScroll: handleScroll,
2430
+ sx: {
2431
+ height: "100%",
2432
+ overflowY: "auto",
2433
+ scrollSnapType: "y mandatory",
2434
+ scrollBehavior: "auto",
2435
+ "&::-webkit-scrollbar": { display: "none" },
2436
+ scrollbarWidth: "none"
2437
+ },
2438
+ children: /* @__PURE__ */ jsx51(
2439
+ Box_default,
2440
+ {
2441
+ sx: { position: "relative", height: contentHeight, width: "100%" },
2442
+ children: Array.from({ length: visibleItemCount }, (_, i) => {
2443
+ const slotIndex = windowStart + i;
2444
+ const logicalIndex = wrap ? mod(baseIndex + slotIndex, N) : slotIndex;
2445
+ const item = items[logicalIndex];
2446
+ if (!item) return null;
2447
+ const isSelected = logicalIndex === currentIndex;
2448
+ return /* @__PURE__ */ jsx51(
2449
+ Box_default,
2450
+ {
2451
+ sx: {
2452
+ position: "absolute",
2453
+ left: 0,
2454
+ right: 0,
2455
+ top: TOP_PADDING + slotIndex * ITEM_HEIGHT,
2456
+ height: ITEM_HEIGHT,
2457
+ display: "flex",
2458
+ alignItems: "center",
2459
+ justifyContent: "center",
2460
+ scrollSnapAlign: "center",
2461
+ pointerEvents: "none",
2462
+ borderRadius: 1,
2463
+ bgcolor: "transparent"
2464
+ },
2465
+ children: /* @__PURE__ */ jsx51(
2466
+ Typography_default,
2467
+ {
2468
+ variant: "body1",
2469
+ color: isSelected ? defaultColors.neutral.dark : defaultColors.neutral.light,
2470
+ fontWeight: isSelected ? 700 : 400,
2471
+ children: getLabel(item)
2472
+ }
2473
+ )
2474
+ },
2475
+ slotIndex
2476
+ );
2477
+ })
2478
+ }
2479
+ )
2480
+ }
2481
+ ),
2482
+ /* @__PURE__ */ jsx51(
2483
+ Box_default,
2484
+ {
2485
+ sx: {
2486
+ position: "absolute",
2487
+ top: 0,
2488
+ left: 0,
2489
+ right: 0,
2490
+ bottom: 0,
2491
+ pointerEvents: "none"
2492
+ },
2493
+ children: /* @__PURE__ */ jsx51(
2494
+ Box_default,
2495
+ {
2496
+ sx: {
2497
+ position: "absolute",
2498
+ top: SELECTED_ROW_INDEX * ITEM_HEIGHT,
2499
+ left: 0,
2500
+ right: 0,
2501
+ width: "100%",
2502
+ height: ITEM_HEIGHT,
2503
+ boxSizing: "border-box",
2504
+ borderTop: "1px solid",
2505
+ borderBottom: "1px solid",
2506
+ borderColor: defaultColors.neutral[300],
2507
+ bgcolor: "transparent"
2508
+ }
2509
+ }
2510
+ )
2511
+ }
2512
+ )
2513
+ ]
2514
+ }
2515
+ );
2516
+ }
2517
+ function valueToUnix(value, format) {
2518
+ if (value === null || value === void 0) return null;
2519
+ if (typeof value === "string" && value.trim() === "") return null;
2520
+ if (format === "unix") {
2521
+ const n = typeof value === "string" ? Number(value) : value;
2522
+ return Number.isFinite(n) ? n : null;
2523
+ }
2524
+ if (format === "jalali" && typeof value === "string") {
2525
+ const parts = value.split("/").map((p) => parseInt(p.trim(), 10));
2526
+ if (parts.length !== 3 || parts.some((p) => !Number.isFinite(p)))
2527
+ return null;
2528
+ try {
2529
+ const d = jalaliToDateUTC(parts[0], parts[1], parts[2]);
2530
+ return Math.floor(d.getTime() / 1e3);
2531
+ } catch {
2532
+ return null;
2533
+ }
2534
+ }
2535
+ if (format === "gregorian" && typeof value === "string") {
2536
+ const d = /* @__PURE__ */ new Date(value + "T00:00:00Z");
2537
+ return Number.isFinite(d.getTime()) ? Math.floor(d.getTime() / 1e3) : null;
2538
+ }
2539
+ return null;
2540
+ }
2541
+ var DEFAULT_MIN_YEAR = 1300;
2542
+ var DEFAULT_MAX_YEAR = 1450;
2543
+ var WheelDatePicker = ({
2544
+ value,
2545
+ dateFormat,
2546
+ valueFormat,
2547
+ onChange,
2548
+ onChangeDateFormat,
2549
+ defaultDate,
2550
+ minDate,
2551
+ maxDate,
2552
+ placeholder = "\u062A\u0627\u0631\u06CC\u062E",
2553
+ title = "\u062A\u0627\u0631\u06CC\u062E",
2554
+ error,
2555
+ helperText,
2556
+ disabled
2557
+ }) => {
2558
+ const resolvedValueFormat = valueFormat ?? dateFormat ?? "unix";
2559
+ const resolvedOnChangeDateFormat = onChangeDateFormat ?? dateFormat ?? "unix";
2560
+ const [drawerOpen, setDrawerOpen] = useState6(false);
2561
+ const [day, setDay] = useState6(1);
2562
+ const [month, setMonth] = useState6(1);
2563
+ const [year, setYear] = useState6(DEFAULT_MIN_YEAR);
2564
+ const valueAsUnix = useMemo2(
2565
+ () => valueToUnix(value, resolvedValueFormat),
2566
+ [value, resolvedValueFormat]
2567
+ );
2568
+ const minYear = useMemo2(() => {
2569
+ if (minDate != null) {
2570
+ try {
2571
+ return getPersianYMD(new Date(minDate * 1e3)).year;
2572
+ } catch {
2573
+ return DEFAULT_MIN_YEAR;
2574
+ }
2575
+ }
2576
+ return DEFAULT_MIN_YEAR;
2577
+ }, [minDate]);
2578
+ const currentJalaliYear = useMemo2(() => {
2579
+ if (maxDate != null) {
2580
+ try {
2581
+ return getPersianYMD(new Date(maxDate * 1e3)).year;
2582
+ } catch {
2583
+ return DEFAULT_MAX_YEAR;
2584
+ }
2585
+ }
2586
+ return DEFAULT_MAX_YEAR;
2587
+ }, [maxDate]);
2588
+ const maxYear = Math.max(currentJalaliYear, minYear);
2589
+ const defaultYMD = useMemo2(() => {
2590
+ const ref = defaultDate != null ? new Date(defaultDate * 1e3) : /* @__PURE__ */ new Date();
2591
+ let ymd;
2592
+ try {
2593
+ ymd = getPersianYMD(ref);
2594
+ } catch {
2595
+ return { year: minYear, month: 1, day: 1 };
2596
+ }
2597
+ const year2 = Math.min(maxYear, Math.max(minYear, ymd.year));
2598
+ const month2 = ymd.month;
2599
+ const maxDay = getDaysInJalaliMonth(year2, month2);
2600
+ const day2 = Math.min(ymd.day, maxDay);
2601
+ return { year: year2, month: month2, day: day2 };
2602
+ }, [minYear, maxYear, defaultDate]);
2603
+ const yearItems = useMemo2(
2604
+ () => Array.from({ length: maxYear - minYear + 1 }, (_, i) => minYear + i).map(
2605
+ (y) => ({ value: y, label: String(y) })
2606
+ ),
2607
+ [maxYear, minYear]
2608
+ );
2609
+ const daysInMonth = getDaysInJalaliMonth(year, month);
2610
+ const dayItems = useMemo2(
2611
+ () => Array.from({ length: daysInMonth }, (_, i) => i + 1).map((d) => ({
2612
+ value: d,
2613
+ label: String(d)
2614
+ })),
2615
+ [daysInMonth]
2616
+ );
2617
+ const monthItems = useMemo2(() => [...PERSIAN_MONTHS], []);
2618
+ useEffect7(() => {
2619
+ const maxDay = getDaysInJalaliMonth(year, month);
2620
+ setDay((d) => d > maxDay ? maxDay : d);
2621
+ }, [year, month]);
2622
+ useEffect7(() => {
2623
+ if (valueAsUnix != null) {
2624
+ const date = new Date(valueAsUnix * 1e3);
2625
+ try {
2626
+ const ymd = getPersianYMD(date);
2627
+ setYear(Math.min(maxYear, Math.max(minYear, ymd.year)));
2628
+ setMonth(ymd.month);
2629
+ setDay(ymd.day);
2630
+ } catch {
2631
+ setYear(minYear);
2632
+ setMonth(1);
2633
+ setDay(1);
2634
+ }
2635
+ } else {
2636
+ setYear(defaultYMD.year);
2637
+ setMonth(defaultYMD.month);
2638
+ setDay(defaultYMD.day);
2639
+ }
2640
+ }, [valueAsUnix, minYear, maxYear, defaultYMD]);
2641
+ const displayText = useMemo2(() => {
2642
+ if (valueAsUnix == null) return "";
2643
+ try {
2644
+ const d = new Date(valueAsUnix * 1e3);
2645
+ const { year: y, month: m, day: dVal } = getPersianYMD(d);
2646
+ return `${y}/${m}/${dVal}`;
2647
+ } catch {
2648
+ return "";
2649
+ }
2650
+ }, [valueAsUnix]);
2651
+ const openDrawer = () => {
2652
+ if (disabled) return;
2653
+ if (valueAsUnix != null) {
2654
+ const date = new Date(valueAsUnix * 1e3);
2655
+ try {
2656
+ const ymd = getPersianYMD(date);
2657
+ setYear(Math.min(maxYear, Math.max(minYear, ymd.year)));
2658
+ setMonth(ymd.month);
2659
+ setDay(ymd.day);
2660
+ } catch {
2661
+ setYear(minYear);
2662
+ setMonth(1);
2663
+ setDay(1);
2664
+ }
2665
+ } else {
2666
+ setYear(defaultYMD.year);
2667
+ setMonth(defaultYMD.month);
2668
+ setDay(defaultYMD.day);
2669
+ }
2670
+ setDrawerOpen(true);
2671
+ };
2672
+ const closeDrawer = () => setDrawerOpen(false);
2673
+ const handleConfirm = () => {
2674
+ try {
2675
+ const jsDate = jalaliToDateUTC(year, month, day);
2676
+ const unixSeconds = Math.floor(jsDate.getTime() / 1e3);
2677
+ const jalaliDate = `${year}/${month}/${day}`;
2678
+ const gregorianDate = `${jsDate.getUTCFullYear()}-${String(jsDate.getUTCMonth() + 1).padStart(2, "0")}-${String(jsDate.getUTCDate()).padStart(2, "0")}`;
2679
+ const value2 = resolvedOnChangeDateFormat === "unix" ? unixSeconds : resolvedOnChangeDateFormat === "jalali" ? jalaliDate : gregorianDate;
2680
+ onChange?.(value2);
2681
+ closeDrawer();
2682
+ } catch {
2683
+ onChange?.(null);
2684
+ closeDrawer();
2685
+ }
2686
+ };
2687
+ return /* @__PURE__ */ jsxs8(Box_default, { children: [
2688
+ /* @__PURE__ */ jsx51(
2689
+ TextField_default,
2690
+ {
2691
+ fullWidth: true,
2692
+ value: displayText,
2693
+ label: title,
2694
+ onClick: openDrawer,
2695
+ error,
2696
+ helperText,
2697
+ disabled,
2698
+ endAdornment: /* @__PURE__ */ jsx51(Calendar2, { size: 20, color: defaultColors.neutral.main }),
2699
+ placeholder,
2700
+ InputProps: {
2701
+ readOnly: true,
2702
+ sx: {
2703
+ cursor: disabled ? "default" : "pointer",
2704
+ borderRadius: "8px",
2705
+ height: 48,
2706
+ "& fieldset": { borderRadius: "8px" }
2707
+ }
2708
+ }
2709
+ }
2710
+ ),
2711
+ /* @__PURE__ */ jsx51(
2712
+ Drawer_default,
2713
+ {
2714
+ isDrawerOpen: drawerOpen,
2715
+ onClose: closeDrawer,
2716
+ sx: {
2717
+ "&.MuiDrawer-root": { maxWidth: 550, mx: "auto" }
2718
+ },
2719
+ children: /* @__PURE__ */ jsxs8(
2720
+ Box_default,
2721
+ {
2722
+ sx: {
2723
+ display: "flex",
2724
+ flexDirection: "column",
2725
+ width: "100%",
2726
+ px: 3.5,
2727
+ py: 6
2728
+ },
2729
+ children: [
2730
+ /* @__PURE__ */ jsxs8(
2731
+ Box_default,
2732
+ {
2733
+ sx: {
2734
+ display: "flex",
2735
+ justifyContent: "space-between",
2736
+ alignItems: "center",
2737
+ width: "100%",
2738
+ mb: 6
2739
+ },
2740
+ children: [
2741
+ /* @__PURE__ */ jsx51(Typography_default, { variant: "h2", fontWeight: 700, children: title }),
2742
+ /* @__PURE__ */ jsx51(
2743
+ IconButton_default,
2744
+ {
2745
+ onClick: closeDrawer,
2746
+ sx: { bgcolor: defaultColors.neutral[100], borderRadius: "8px" },
2747
+ children: /* @__PURE__ */ jsx51(
2748
+ Add4,
2749
+ {
2750
+ size: 20,
2751
+ color: defaultColors.neutral.main,
2752
+ style: { transform: "rotate(45deg)" }
2753
+ }
2754
+ )
2755
+ }
2756
+ )
2757
+ ]
2758
+ }
2759
+ ),
2760
+ /* @__PURE__ */ jsxs8(
2761
+ Box_default,
2762
+ {
2763
+ sx: {
2764
+ display: "flex",
2765
+ width: "100%",
2766
+ px: 2,
2767
+ pb: 2,
2768
+ borderBottom: "1px solid"
2769
+ },
2770
+ children: [
2771
+ /* @__PURE__ */ jsx51(
2772
+ Typography_default,
2773
+ {
2774
+ variant: "subtitle2",
2775
+ fontWeight: 700,
2776
+ sx: { flex: 1, textAlign: "center" },
2777
+ children: "\u0631\u0648\u0632"
2778
+ }
2779
+ ),
2780
+ /* @__PURE__ */ jsx51(
2781
+ Typography_default,
2782
+ {
2783
+ variant: "subtitle2",
2784
+ fontWeight: 700,
2785
+ sx: { flex: 1, textAlign: "center" },
2786
+ children: "\u0645\u0627\u0647"
2787
+ }
2788
+ ),
2789
+ /* @__PURE__ */ jsx51(
2790
+ Typography_default,
2791
+ {
2792
+ variant: "subtitle2",
2793
+ fontWeight: 700,
2794
+ sx: { flex: 1, textAlign: "center" },
2795
+ children: "\u0633\u0627\u0644"
2796
+ }
2797
+ )
2798
+ ]
2799
+ }
2800
+ ),
2801
+ /* @__PURE__ */ jsxs8(
2802
+ Box_default,
2803
+ {
2804
+ sx: {
2805
+ display: "flex",
2806
+ alignItems: "stretch",
2807
+ width: "100%",
2808
+ borderRadius: 2,
2809
+ p: 2,
2810
+ mb: 4,
2811
+ pt: 1.5,
2812
+ minHeight: ITEM_HEIGHT * WHEEL_VISIBLE_ITEMS
2813
+ },
2814
+ children: [
2815
+ /* @__PURE__ */ jsx51(
2816
+ FlatWheelColumn,
2817
+ {
2818
+ items: dayItems,
2819
+ value: { value: day, label: String(day) },
2820
+ getKey: (i) => i.value,
2821
+ getLabel: (i) => i.label,
2822
+ onSelect: (i) => setDay(i.value)
2823
+ }
2824
+ ),
2825
+ /* @__PURE__ */ jsx51(
2826
+ FlatWheelColumn,
2827
+ {
2828
+ items: monthItems,
2829
+ value: monthItems.find((m) => m.value === month) ?? monthItems[0],
2830
+ getKey: (i) => i.value,
2831
+ getLabel: (i) => i.label,
2832
+ onSelect: (i) => setMonth(i.value)
2833
+ }
2834
+ ),
2835
+ /* @__PURE__ */ jsx51(
2836
+ FlatWheelColumn,
2837
+ {
2838
+ items: yearItems,
2839
+ value: yearItems.find((y) => y.value === year) ?? yearItems[0],
2840
+ getKey: (i) => i.value,
2841
+ getLabel: (i) => i.label,
2842
+ onSelect: (i) => setYear(i.value),
2843
+ wrap: yearItems.length >= 3
2844
+ }
2845
+ )
2846
+ ]
2847
+ }
2848
+ ),
2849
+ /* @__PURE__ */ jsx51(Button_default, { variant: "contained", fullWidth: true, onClick: handleConfirm, children: "\u062A\u0623\u06CC\u06CC\u062F" })
2850
+ ]
2851
+ }
2852
+ )
2853
+ }
2854
+ )
2855
+ ] });
2856
+ };
2857
+ var WheelDatePicker_default = WheelDatePicker;
2858
+
2859
+ // src/components/DataGrid.tsx
2860
+ import { useMemo as useMemo3, useCallback } from "react";
2861
+ import {
2862
+ MaterialReactTable,
2863
+ useMaterialReactTable
2864
+ } from "material-react-table";
2865
+ import { MRT_Localization_FA } from "material-react-table/locales/fa";
2866
+ import { useMaterialReactTable as useMaterialReactTable2 } from "material-react-table";
2867
+ import { jsx as jsx52 } from "react/jsx-runtime";
2868
+ var DataGrid = ({
2869
+ columns,
2870
+ data,
2871
+ localization,
2872
+ layoutMode = "grid",
2873
+ enableRowActions,
2874
+ // Extract MRT options to merge with defaults
2875
+ initialState,
2876
+ displayColumnDefOptions,
2877
+ muiTablePaperProps,
2878
+ muiTableContainerProps,
2879
+ muiTableHeadCellProps,
2880
+ muiTableBodyCellProps,
2881
+ muiTableBodyRowProps,
2882
+ muiSelectCheckboxProps,
2883
+ ...mrtOptions
2884
+ }) => {
2885
+ const mergedLocalization = useMemo3(
2886
+ () => ({ ...MRT_Localization_FA, ...localization }),
2887
+ [localization]
2888
+ );
2889
+ const columnOrder = useMemo3(() => {
2890
+ const dataColumnIds = columns.map((col) => {
2891
+ if ("accessorKey" in col && col.accessorKey)
2892
+ return String(col.accessorKey);
2893
+ if ("id" in col && col.id) return String(col.id);
2894
+ return void 0;
2895
+ }).filter((id) => Boolean(id));
2896
+ return [
2897
+ "mrt-row-expand",
2898
+ "mrt-row-select",
2899
+ "mrt-row-numbers",
2900
+ ...dataColumnIds,
2901
+ "mrt-row-actions"
2902
+ ];
2903
+ }, [columns]);
2904
+ const mergedInitialState = useMemo3(
2905
+ () => ({
2906
+ density: "compact",
2907
+ columnOrder,
2908
+ expanded: {},
2909
+ ...initialState
2910
+ }),
2911
+ [columnOrder, initialState]
2912
+ );
2913
+ const defaultPaperProps = useMemo3(
2914
+ () => ({
2915
+ elevation: 0,
2916
+ sx: {
2917
+ width: "100%",
2918
+ borderRadius: "12px",
2919
+ overflow: "hidden"
2920
+ }
2921
+ }),
2922
+ []
2923
+ );
2924
+ const defaultContainerProps = useMemo3(
2925
+ () => ({
2926
+ sx: {
2927
+ width: "100%",
2928
+ maxHeight: `calc(100vh - 300px)`
2929
+ }
2930
+ }),
2931
+ []
2932
+ );
2933
+ const defaultHeadCellProps = useMemo3(
2934
+ () => ({
2935
+ sx: {
2936
+ flexDirection: "row !important",
2937
+ backgroundColor: "#f4f6fa",
2938
+ fontWeight: 500,
2939
+ fontSize: "16px",
2940
+ color: "#4f545e",
2941
+ borderBottom: "1px solid #d6d9df",
2942
+ textAlign: "right",
2943
+ p: "0.35rem 0.5rem",
2944
+ "& .Mui-TableHeadCell-Content": {
2945
+ justifyContent: "flex-end",
2946
+ flexDirection: "row !important",
2947
+ gap: "2px"
2948
+ },
2949
+ "& .Mui-TableHeadCell-Content-Labels": {
2950
+ flexDirection: "row !important",
2951
+ gap: "2px"
2952
+ },
2953
+ "&.MuiTableCell-alignRight": {
2954
+ textAlign: "right"
2955
+ },
2956
+ "&.MuiTableCell-alignLeft": {
2957
+ textAlign: "left"
2958
+ },
2959
+ "&.MuiTableCell-alignCenter": {
2960
+ textAlign: "center"
2961
+ },
2962
+ "&.MuiTableCell-alignRight .Mui-TableHeadCell-Content, &.MuiTableCell-alignRight .Mui-TableHeadCell-Content-Labels": {
2963
+ flexDirection: "row-reverse !important"
2964
+ },
2965
+ "&.MuiTableCell-alignLeft .Mui-TableHeadCell-Content, &.MuiTableCell-alignLeft .Mui-TableHeadCell-Content-Labels": {
2966
+ flexDirection: "row !important"
2967
+ },
2968
+ "&.MuiTableCell-alignCenter .Mui-TableHeadCell-Content, &.MuiTableCell-alignCenter .Mui-TableHeadCell-Content-Labels": {
2969
+ flexDirection: "row !important"
2970
+ },
2971
+ "&.MuiTableCell-alignLeft .Mui-TableHeadCell-Content": {
2972
+ justifyContent: "flex-start"
2973
+ },
2974
+ "&.MuiTableCell-alignCenter .Mui-TableHeadCell-Content": {
2975
+ justifyContent: "center"
2976
+ },
2977
+ "& .Mui-TableHeadCell-Content-Actions": {
2978
+ gap: "0px",
2979
+ marginLeft: "-2px",
2980
+ marginRight: "-2px",
2981
+ "& .MuiIconButton-root": {
2982
+ width: 12,
2983
+ height: 12,
2984
+ minWidth: 12,
2985
+ minHeight: 12,
2986
+ padding: "2px"
2987
+ },
2988
+ "& .MuiIconButton-root svg": {
2989
+ fontSize: "0.875rem"
2990
+ }
2991
+ },
2992
+ "& .Mui-TableHeadCell-Content-Labels .MuiIconButton-root": {
2993
+ width: 12,
2994
+ height: 12,
2995
+ minWidth: 12,
2996
+ minHeight: 12,
2997
+ padding: "1px"
2998
+ },
2999
+ "& .MuiTableSortLabel-root": {
3000
+ width: "1.5ch",
3001
+ minWidth: "1.5ch"
3002
+ },
3003
+ "& .MuiTableSortLabel-icon": {
3004
+ fontSize: "0.875rem"
3005
+ }
3006
+ }
3007
+ }),
3008
+ []
3009
+ );
3010
+ const defaultBodyCellProps = useMemo3(
3011
+ () => ({
3012
+ sx: {
3013
+ flexDirection: "row !important"
3014
+ }
3015
+ }),
3016
+ []
3017
+ );
3018
+ const defaultCheckboxProps = useMemo3(
3019
+ () => ({
3020
+ sx: {
3021
+ color: "#d6d9df",
3022
+ "&.Mui-checked": {
3023
+ color: "#0C8CE9"
3024
+ }
3025
+ }
3026
+ }),
3027
+ []
3028
+ );
3029
+ const defaultBodyRowProps = useCallback(
3030
+ ({ row }) => ({
3031
+ sx: {
3032
+ backgroundColor: row.getIsSelected() ? "#E6F4FD" : void 0,
3033
+ "&:nth-of-type(odd)": {
3034
+ backgroundColor: row.getIsSelected() ? "#E6F4FD" : "white"
3035
+ },
3036
+ "&:nth-of-type(even)": {
3037
+ backgroundColor: row.getIsSelected() ? "#E6F4FD" : "#F4F6FA"
3038
+ },
3039
+ "&:hover": {
3040
+ backgroundColor: row.getIsSelected() ? "#E6F4FD" : "#f4f6fa"
3041
+ },
3042
+ "& .MuiTableCell-root": {
3043
+ textAlign: "right",
3044
+ fontSize: "14px",
3045
+ flexDirection: "row !important"
3046
+ }
3047
+ }
3048
+ }),
3049
+ []
3050
+ );
3051
+ const muiColumnActionsButtonPropsStable = useMemo3(
3052
+ () => ({
3053
+ sx: {
3054
+ height: 12,
3055
+ width: 12,
3056
+ minWidth: 12,
3057
+ minHeight: 12,
3058
+ m: "0 -1px",
3059
+ "& svg": { fontSize: "0.875rem" }
3060
+ }
3061
+ }),
3062
+ []
3063
+ );
3064
+ const muiColumnDragHandlePropsStable = useMemo3(
3065
+ () => ({
3066
+ sx: {
3067
+ width: 12,
3068
+ height: 12,
3069
+ minWidth: 12,
3070
+ minHeight: 12,
3071
+ m: "0 -1px",
3072
+ "& svg": { fontSize: "0.75rem" }
3073
+ }
3074
+ }),
3075
+ []
3076
+ );
3077
+ const mergedDisplayColumnDefOptions = useMemo3(() => {
3078
+ const baseOptions = displayColumnDefOptions ?? {};
3079
+ const baseRowActions = baseOptions["mrt-row-actions"] ?? {};
3080
+ if (!enableRowActions && Object.keys(baseRowActions).length === 0) {
3081
+ return baseOptions;
3082
+ }
3083
+ const minActionWidth = 160;
3084
+ const rawSize = Number(
3085
+ baseRowActions.size ?? baseRowActions.minSize ?? minActionWidth
3086
+ );
3087
+ const rawMin = Number(
3088
+ baseRowActions.minSize ?? baseRowActions.size ?? minActionWidth
3089
+ );
3090
+ const rawMax = Number(
3091
+ baseRowActions.maxSize ?? baseRowActions.size ?? minActionWidth
3092
+ );
3093
+ return {
3094
+ ...baseOptions,
3095
+ "mrt-row-actions": {
3096
+ ...baseRowActions,
3097
+ header: baseRowActions.header ?? "\u0639\u0645\u0644\u06CC\u0627\u062A",
3098
+ size: Math.max(rawSize, minActionWidth),
3099
+ minSize: Math.max(rawMin, minActionWidth),
3100
+ maxSize: Math.max(rawMax, minActionWidth)
3101
+ }
3102
+ };
3103
+ }, [displayColumnDefOptions, enableRowActions]);
3104
+ const table = useMaterialReactTable({
3105
+ columns,
3106
+ data,
3107
+ localization: mergedLocalization,
3108
+ layoutMode,
3109
+ enableRowActions,
3110
+ displayColumnDefOptions: mergedDisplayColumnDefOptions,
3111
+ columnResizeDirection: "rtl",
3112
+ initialState: mergedInitialState,
3113
+ // Use user props if provided, otherwise use defaults
3114
+ muiTablePaperProps: muiTablePaperProps ?? defaultPaperProps,
3115
+ muiTableContainerProps: muiTableContainerProps ?? defaultContainerProps,
3116
+ muiTableHeadCellProps: muiTableHeadCellProps ?? defaultHeadCellProps,
3117
+ muiTableBodyCellProps: muiTableBodyCellProps ?? defaultBodyCellProps,
3118
+ muiSelectCheckboxProps: muiSelectCheckboxProps ?? defaultCheckboxProps,
3119
+ muiTableBodyRowProps: muiTableBodyRowProps ?? defaultBodyRowProps,
3120
+ // Compact column header buttons (sort, drag, filter, column menu)
3121
+ muiColumnActionsButtonProps: muiColumnActionsButtonPropsStable,
3122
+ muiColumnDragHandleProps: muiColumnDragHandlePropsStable,
3123
+ // Spread all other MRT options (user can override anything)
3124
+ ...mrtOptions
3125
+ });
3126
+ return /* @__PURE__ */ jsx52("div", { style: { direction: "rtl", width: "100%" }, children: /* @__PURE__ */ jsx52(MaterialReactTable, { table }) });
3127
+ };
3128
+ var DataGrid_default = DataGrid;
3129
+
3130
+ // src/components/MultiSelect.tsx
3131
+ import { Add as Add5, ArrowDown2, ArrowUp2 } from "iconsax-react";
3132
+ import { useState as useState7 } from "react";
3133
+ import { jsx as jsx53, jsxs as jsxs9 } from "react/jsx-runtime";
3134
+ var MultiSelect = ({
3135
+ value,
3136
+ onChange,
3137
+ options,
3138
+ minWidth = "13rem",
3139
+ label = "\u0627\u0646\u062A\u062E\u0627\u0628 \u0645\u0648\u0627\u0631\u062F"
3140
+ }) => {
3141
+ const [isSelectOpen, setIsSelectOpen] = useState7(false);
3142
+ const handleChange = (event) => {
3143
+ const selectedValue = event.target.value;
3144
+ onChange(
3145
+ typeof selectedValue === "string" ? selectedValue.split(",") : selectedValue
3146
+ );
3147
+ };
3148
+ const handleRemoveSelectedItem = (item) => {
3149
+ onChange(value.filter((selected) => selected !== item));
3150
+ };
3151
+ return /* @__PURE__ */ jsxs9(FormControl_default, { sx: { minWidth }, children: [
3152
+ /* @__PURE__ */ jsx53(InputLabel_default, { id: "multi-select-label", children: label }),
3153
+ /* @__PURE__ */ jsx53(
3154
+ Select_default,
3155
+ {
3156
+ id: "multi-select",
3157
+ labelId: "multi-select-label",
3158
+ label,
3159
+ value,
3160
+ onChange: handleChange,
3161
+ onOpen: () => setIsSelectOpen(true),
3162
+ onClose: () => setIsSelectOpen(false),
3163
+ multiple: true,
3164
+ IconComponent: () => /* @__PURE__ */ jsx53(Box_default, { mr: 4, mt: 1.5, children: isSelectOpen ? /* @__PURE__ */ jsx53(ArrowUp2, { size: 18, color: defaultColors.neutral.dark }) : /* @__PURE__ */ jsx53(ArrowDown2, { size: 18, color: defaultColors.neutral.dark }) }),
3165
+ sx: {
3166
+ height: 48,
3167
+ borderRadius: 2,
3168
+ "& .MuiSelect-select": {
3169
+ display: "flex",
3170
+ alignItems: "center",
3171
+ height: "48px !important",
3172
+ minHeight: "48px !important",
3173
+ boxSizing: "border-box",
3174
+ overflowX: "auto",
3175
+ overflowY: "hidden",
3176
+ whiteSpace: "nowrap",
3177
+ py: 0
3178
+ }
3179
+ },
3180
+ renderValue: (selected) => {
3181
+ const selectedItems = selected;
3182
+ return /* @__PURE__ */ jsx53(Box_default, { sx: { display: "flex", flexWrap: "nowrap", gap: 1 }, children: selectedItems.map((item) => /* @__PURE__ */ jsxs9(
3183
+ Box_default,
3184
+ {
3185
+ sx: {
3186
+ display: "inline-flex",
3187
+ alignItems: "center",
3188
+ gap: 2,
3189
+ px: 3,
3190
+ py: 1.5,
3191
+ bgcolor: defaultColors.neutral[100],
3192
+ borderRadius: 999
3193
+ },
3194
+ children: [
3195
+ options.find((option) => option.value === item)?.label ?? item,
3196
+ /* @__PURE__ */ jsx53(
3197
+ IconButton_default,
3198
+ {
3199
+ onMouseDown: (event) => event.stopPropagation(),
3200
+ onClick: () => handleRemoveSelectedItem(item),
3201
+ sx: {
3202
+ p: 0,
3203
+ minWidth: "auto",
3204
+ color: defaultColors.neutral.main
3205
+ },
3206
+ children: /* @__PURE__ */ jsx53("div", { style: { width: 18, height: 18, marginBottom: 6 }, children: /* @__PURE__ */ jsx53(
3207
+ Add5,
3208
+ {
3209
+ size: 18,
3210
+ color: defaultColors.neutral.main,
3211
+ style: { transform: "rotate(45deg)" }
3212
+ }
3213
+ ) })
3214
+ }
3215
+ )
3216
+ ]
3217
+ },
3218
+ item
3219
+ )) });
3220
+ },
3221
+ children: options.map((option) => /* @__PURE__ */ jsx53(MenuItem_default, { value: option.value, children: option.label }, option.value))
3222
+ }
3223
+ )
3224
+ ] });
3225
+ };
3226
+ var MultiSelect_default = MultiSelect;
3227
+
3228
+ // src/providers/ThemeProvider.tsx
3229
+ import { ThemeProvider as MUIThemeProvider } from "@mui/material/styles";
3230
+ import { CacheProvider } from "@emotion/react";
3231
+ import createCache from "@emotion/cache";
3232
+ import rtlPlugin from "stylis-plugin-rtl";
3233
+ import { prefixer } from "stylis";
3234
+ import { createTheme } from "@mui/material/styles";
3235
+
3236
+ // src/constants/typography.ts
3237
+ var uiTypography = {
3238
+ display1: {
3239
+ fontSize: "32px",
3240
+ fontWeight: 700
3241
+ },
3242
+ display2: {
3243
+ fontSize: "24px",
3244
+ fontWeight: 700
3245
+ },
3246
+ display3: {
3247
+ fontSize: "20px",
3248
+ fontWeight: 700
3249
+ },
3250
+ h1: {
3251
+ fontSize: "18px",
3252
+ fontWeight: 500
3253
+ },
3254
+ h2: {
3255
+ fontSize: "16px",
3256
+ fontWeight: 500
3257
+ },
3258
+ h3: {
3259
+ fontSize: "14px",
3260
+ fontWeight: 500
3261
+ },
3262
+ title1: {
3263
+ fontSize: "16px",
3264
+ fontWeight: 500
3265
+ },
3266
+ title2: {
3267
+ fontSize: "14px",
3268
+ fontWeight: 500
3269
+ },
3270
+ title3: {
3271
+ fontSize: "12px",
3272
+ fontWeight: 500
3273
+ },
3274
+ title4: {
3275
+ fontSize: "10px",
3276
+ fontWeight: 500
3277
+ },
3278
+ input1: {
3279
+ fontSize: "16px",
3280
+ fontWeight: 500
3281
+ },
3282
+ input2: {
3283
+ fontSize: "14px",
3284
+ fontWeight: 500
3285
+ },
3286
+ input3: {
3287
+ fontSize: "12px",
3288
+ fontWeight: 500
3289
+ },
3290
+ button1: {
3291
+ fontSize: "16px",
3292
+ fontWeight: 700
3293
+ },
3294
+ button2: {
3295
+ fontSize: "14px",
3296
+ fontWeight: 700
3297
+ },
3298
+ button3: {
3299
+ fontSize: "12px",
3300
+ fontWeight: 700
3301
+ },
3302
+ body1: {
3303
+ fontSize: "14px",
3304
+ fontWeight: 500
3305
+ },
3306
+ body2: {
3307
+ fontSize: "12px",
3308
+ fontWeight: 500
3309
+ },
3310
+ label1: {
3311
+ fontSize: "12px",
3312
+ fontWeight: 400
3313
+ },
3314
+ label2: {
3315
+ fontSize: "10px",
3316
+ fontWeight: 400
3317
+ }
3318
+ };
3319
+
3320
+ // src/providers/ThemeProvider.tsx
3321
+ import { jsx as jsx54 } from "react/jsx-runtime";
3322
+ var ThemeProvider = ({
3323
+ children,
3324
+ appColors,
3325
+ dir
3326
+ }) => {
3327
+ const cacheRtl = createCache({
3328
+ key: "muirtl",
3329
+ stylisPlugins: [prefixer, rtlPlugin]
3330
+ });
3331
+ const cacheLtr = createCache({
3332
+ key: "muiltr",
3333
+ stylisPlugins: [prefixer]
3334
+ });
3335
+ const themeOptions = {
3336
+ // colorSchemes: {
3337
+ // dark: false,
3338
+ // },
3339
+ palette: {
3340
+ ...appColors,
3341
+ ...defaultColors
3342
+ },
3343
+ typography: {
3344
+ fontFamily: '"IRANYekanX", sans-serif',
3345
+ ...uiTypography
3346
+ },
3347
+ spacing: 4
3348
+ };
3349
+ const theme = createTheme(themeOptions);
3350
+ return /* @__PURE__ */ jsx54(CacheProvider, { value: dir === "rtl" ? cacheRtl : cacheLtr, children: /* @__PURE__ */ jsx54(MUIThemeProvider, { theme, children }) });
3351
+ };
3352
+ var ThemeProvider_default = ThemeProvider;
3353
+
3354
+ // src/providers/SPAThemeProvider.tsx
3355
+ import { ThemeProvider as MUIThemeProvider2 } from "@mui/material/styles";
3356
+ import { createTheme as createTheme2 } from "@mui/material/styles";
3357
+ import rtlPlugin2 from "stylis-plugin-rtl";
3358
+ import { prefixer as prefixer2 } from "stylis";
3359
+ import { CacheProvider as CacheProvider2 } from "@emotion/react";
3360
+ import createCache2 from "@emotion/cache";
3361
+ import { jsx as jsx55 } from "react/jsx-runtime";
3362
+ var SPAThemeProvider = ({
3363
+ children,
3364
+ appColors,
3365
+ dir,
3366
+ defaultColors: defaultColorsProp,
3367
+ themeOptions
3368
+ }) => {
3369
+ const paletteDefaults = defaultColorsProp ?? defaultColors;
3370
+ const theme = createTheme2({
3371
+ direction: dir,
3372
+ colorSchemes: {
3373
+ dark: true
3374
+ },
3375
+ palette: {
3376
+ ...appColors,
3377
+ ...paletteDefaults
3378
+ },
3379
+ typography: {
3380
+ fontFamily: '"IRANYekanXFaNum", sans-serif',
3381
+ ...uiTypography
3382
+ },
3383
+ spacing: 4,
3384
+ ...themeOptions
3385
+ });
3386
+ const cacheRtl = createCache2({
3387
+ key: "muirtl",
3388
+ stylisPlugins: [prefixer2, rtlPlugin2]
3389
+ });
3390
+ const cacheLtr = createCache2({
3391
+ key: "muiltr",
3392
+ stylisPlugins: [prefixer2]
3393
+ });
3394
+ return /* @__PURE__ */ jsx55(CacheProvider2, { value: dir === "rtl" ? cacheRtl : cacheLtr, children: /* @__PURE__ */ jsx55(MUIThemeProvider2, { theme, defaultMode: "light", children }) });
3395
+ };
3396
+ var SPAThemeProvider_default = SPAThemeProvider;
3397
+
3398
+ // src/hooks/index.ts
3399
+ import { useLocalStorage } from "@wojtekmaj/react-hooks";
3400
+ import { useWindowHeight } from "@wojtekmaj/react-hooks";
3401
+ import { useWindowWidth } from "@wojtekmaj/react-hooks";
3402
+ import { useColorScheme } from "@mui/material/styles";
3403
+ import { useTheme as useTheme2 } from "@mui/material/styles";
3404
+
3405
+ // src/hooks/useErrorHandler.ts
3406
+ import { useCallback as useCallback2, useState as useState9 } from "react";
3407
+
3408
+ // src/context/MessageHandler.tsx
3409
+ import {
3410
+ createContext,
3411
+ useState as useState8
3412
+ } from "react";
3413
+ import { jsx as jsx56, jsxs as jsxs10 } from "react/jsx-runtime";
3414
+ var MessageContext = createContext(
3415
+ void 0
3416
+ );
3417
+ var MessageProvider = ({
3418
+ children,
3419
+ toastPosition = { vertical: "top", horizontal: "left" },
3420
+ width = "90%"
3421
+ }) => {
3422
+ const [message, setMessage] = useState8(null);
3423
+ const [open, setOpen] = useState8(false);
3424
+ const duration = 4e3;
3425
+ const showMessage = (text, severity, showUndo = false, isWide = false) => {
3426
+ setMessage({ text, severity, showUndo, isWide });
3427
+ setOpen(true);
3428
+ };
3429
+ const handleClose = () => {
3430
+ setOpen(false);
3431
+ };
3432
+ const contextValue = {
3433
+ showMessage,
3434
+ inDesktop: toastPosition,
3435
+ width
3436
+ };
3437
+ return /* @__PURE__ */ jsxs10(MessageContext.Provider, { value: contextValue, children: [
3438
+ children,
3439
+ message && /* @__PURE__ */ jsx56(
3440
+ Toast_default,
3441
+ {
3442
+ open,
3443
+ handleClose,
3444
+ duration,
3445
+ message,
3446
+ width,
3447
+ anchorOrigin: toastPosition,
3448
+ isWide: message.isWide
3449
+ }
3450
+ )
3451
+ ] });
3452
+ };
3453
+
3454
+ // src/hooks/useMessage.ts
3455
+ import { useContext as useContext2 } from "react";
3456
+ var useMessage = () => {
3457
+ const context = useContext2(MessageContext);
3458
+ if (!context) {
3459
+ throw new Error("useMessage must be used within a MessageProvider");
3460
+ }
3461
+ return context;
3462
+ };
3463
+
3464
+ // src/hooks/useErrorHandler.ts
3465
+ var general_err_msg = "\u0645\u0634\u06A9\u0644\u06CC \u067E\u06CC\u0634 \u0627\u0648\u0645\u062F\u0647";
3466
+ var errorHandler = (err) => {
3467
+ if (err instanceof Error) {
3468
+ console.log("\u{1F680} ~ err coooore:", err);
3469
+ const errorData = JSON.parse(err.message);
3470
+ console.log(errorData);
3471
+ if (errorData?.message) return errorData.message;
3472
+ else if (errorData?.meta?.error_fields) return errorData.meta.error_fields;
3473
+ else return general_err_msg;
3474
+ } else return general_err_msg;
3475
+ };
3476
+ var useErrorHandler = () => {
3477
+ const { showMessage } = useMessage();
3478
+ const [errFields, setErrFields] = useState9();
3479
+ const [errorMessage, setErrorMessage] = useState9();
3480
+ const handleError = useCallback2(
3481
+ (error, fieldHandler, isWide = false) => {
3482
+ const err = errorHandler(error);
3483
+ if (typeof err === "string") {
3484
+ setErrorMessage(err);
3485
+ showMessage(err, "error", false, isWide);
3486
+ } else {
3487
+ setErrFields(err);
3488
+ if (fieldHandler) {
3489
+ err.forEach((err2) => {
3490
+ fieldHandler(err2.field, { message: err2.message });
3491
+ });
3492
+ }
3493
+ }
3494
+ },
3495
+ [setErrFields]
3496
+ );
3497
+ return { handleError, errFields, errorMessage };
3498
+ };
3499
+
3500
+ // src/hooks/useWebOtpListener.ts
3501
+ import { useEffect as useEffect9 } from "react";
3502
+ function useWebOtpListener(setOtp) {
3503
+ useEffect9(() => {
3504
+ const ac = new AbortController();
3505
+ if (typeof window !== "undefined" && "OTPCredential" in window && navigator.credentials) {
3506
+ navigator.credentials.get({
3507
+ otp: { transport: ["sms"] },
3508
+ signal: ac.signal
3509
+ }).then((credential) => {
3510
+ if (credential?.code) {
3511
+ setOtp(credential.code);
3512
+ }
3513
+ ac.abort();
3514
+ }).catch((err) => {
3515
+ console.error("WebOTP failed:", err);
3516
+ ac.abort();
3517
+ });
3518
+ }
3519
+ return () => {
3520
+ ac.abort();
3521
+ };
3522
+ }, [setOtp]);
3523
+ }
3524
+
3525
+ // src/libs/create-api-request.ts
3526
+ import axios from "axios";
3527
+ var createApiRequest = (baseConfig, onRequestFulfilled, onRequestRejected, onResponseFulfilled, onResponseRejected, disableAuthHeader) => {
3528
+ const pathname = typeof window !== "undefined" ? window.location.pathname : "";
3529
+ const isPanelClient = /^\/([^\/]+\/)?panel(\/|$)/.test(pathname);
3530
+ if (!baseConfig) baseConfig = {};
3531
+ const { redirect: defaultRedirect, ...axiosDefaults } = baseConfig;
3532
+ const axiosInstance = axios.create({
3533
+ ...axiosDefaults,
3534
+ withCredentials: axiosDefaults.withCredentials ?? true
3535
+ });
3536
+ axiosInstance.defaults.headers.common.Accept = "application/json";
3537
+ axiosInstance.defaults.headers.common["Content-Type"] = "application/json";
3538
+ if (typeof window !== "undefined" && !disableAuthHeader) {
3539
+ if (isPanelClient) {
3540
+ axiosInstance.defaults.headers.common.Authorization = localStorage.getItem("panel_auth_token");
3541
+ } else {
3542
+ axiosInstance.defaults.headers.common.Authorization = localStorage.getItem("auth_token");
3543
+ }
3544
+ }
3545
+ axiosInstance.interceptors.request.use(
3546
+ async (config) => {
3547
+ if (onRequestFulfilled) config = onRequestFulfilled(config);
3548
+ return config;
3549
+ },
3550
+ (error) => {
3551
+ console.log("\u{1F680} ~ apiRequest.interceptors.request. error:", error);
3552
+ return Promise.reject(error);
3553
+ }
3554
+ );
3555
+ axiosInstance.interceptors.response.use(
3556
+ async (response) => {
3557
+ if (onResponseFulfilled) response = await onResponseFulfilled(response);
3558
+ return response;
3559
+ },
3560
+ (error) => {
3561
+ console.log(
3562
+ "\u{1F680} ~ Axios original error in apiRequest.interceptors.response: ",
3563
+ error
3564
+ );
3565
+ if (onResponseRejected) {
3566
+ const e = onResponseRejected(error);
3567
+ if (e) return Promise.reject(e);
3568
+ }
3569
+ if (error.status === 401) {
3570
+ if (typeof window !== "undefined") {
3571
+ const host = localStorage.getItem("host_app");
3572
+ console.log("\u{1F680} ~ createApiRequest ~ host:", host);
3573
+ console.log("client 401, redirect to auth");
3574
+ if (host === "ios" || host === "ios_wrapper") {
3575
+ console.log("logout ios");
3576
+ window.webkit.messageHandlers.logout.postMessage("");
3577
+ } else if (host === "android" || host === "android_wrapper") {
3578
+ console.log("logout android");
3579
+ window.injast_android_app.logout();
3580
+ } else {
3581
+ localStorage.clear();
3582
+ const requestRedirect = error.config?.redirect ?? defaultRedirect;
3583
+ let href = isPanelClient ? "/panel/auth/login" : "/auth/login";
3584
+ if (requestRedirect) {
3585
+ href += `?redirect=${requestRedirect}`;
3586
+ }
3587
+ window.location.href = href;
3588
+ }
3589
+ return;
3590
+ } else {
3591
+ console.log("401, throw 401 error");
3592
+ const e = JSON.stringify({ message: "401" });
3593
+ return Promise.reject(e);
3594
+ }
3595
+ } else {
3596
+ error.response.data.error_status = error.status;
3597
+ console.log(
3598
+ "\u{1F680} ~ axios on response => error.response.data: ",
3599
+ error?.response?.data
3600
+ );
3601
+ const errorString = JSON.stringify(error?.response?.data || "");
3602
+ const e = new Error(errorString);
3603
+ return Promise.reject(e);
3604
+ }
3605
+ }
3606
+ );
3607
+ return axiosInstance;
3608
+ };
3609
+
3610
+ // src/libs/create-sentry-instrument.ts
3611
+ import * as Sentry from "@sentry/react";
3612
+ function initSentry({ dsn, appName, release, environment }) {
3613
+ Sentry.init({
3614
+ dsn,
3615
+ environment,
3616
+ release: `${appName}@${release ?? "dev"}`,
3617
+ tracesSampleRate: 1
3618
+ });
3619
+ }
3620
+
3621
+ // src/libs/create-logger.ts
3622
+ function formatTimestamp() {
3623
+ const date = /* @__PURE__ */ new Date();
3624
+ const pad = (n) => n.toString().padStart(2, "0");
3625
+ const year = date.getFullYear();
3626
+ const month = pad(date.getMonth() + 1);
3627
+ const day = pad(date.getDate());
3628
+ const hours = pad(date.getHours());
3629
+ const minutes = pad(date.getMinutes());
3630
+ const seconds = pad(date.getSeconds());
3631
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
3632
+ }
3633
+ function createLogger(options, message, ...optionalParams) {
3634
+ if (!options.enabled) return;
3635
+ const prefix = options.prefix ?? "[AppLog]";
3636
+ const timestamp = options.timestamp ? `[${formatTimestamp()}]` : "";
3637
+ const consoleParts = [prefix];
3638
+ if (timestamp) consoleParts.push(timestamp + ":");
3639
+ console.log(...consoleParts, message, ...optionalParams);
3640
+ if (typeof window !== "undefined") {
3641
+ if (window.webkit?.messageHandlers?.consoleLog) {
3642
+ try {
3643
+ const serialized = JSON.stringify({ message, optionalParams });
3644
+ window.webkit.messageHandlers.consoleLog.postMessage(
3645
+ `${prefix} ${timestamp} ${serialized}`
3646
+ );
3647
+ } catch (err) {
3648
+ console.warn("Failed to post message to iOS webkit handler:", err);
3649
+ }
3650
+ }
3651
+ } else {
3652
+ if (typeof process !== "undefined") {
3653
+ const text = [prefix, timestamp, message, ...optionalParams].map(String).join(" ") + "\n";
3654
+ process.stdout.write(text);
3655
+ }
3656
+ }
3657
+ }
3658
+
3659
+ // src/utils/delay.ts
3660
+ function delay(ms) {
3661
+ return new Promise((resolve) => setTimeout(resolve, ms));
3662
+ }
3663
+
3664
+ // src/utils/createQueryParams.ts
3665
+ import { isEmpty } from "lodash";
3666
+ var createQueryParams = (obj) => {
3667
+ if (isEmpty(obj)) return "";
3668
+ return Object.entries(obj).map(([key, value]) => value && `${key}=${encodeURI(value.toString())}`).filter((i) => i).join("&");
3669
+ };
3670
+
3671
+ // src/utils/convertRialToToman.ts
3672
+ function convertRialToToman(input) {
3673
+ let num = typeof input === "string" ? String(input) : input;
3674
+ if (typeof num === "string") {
3675
+ num = parseFloat(num.replace(/,/g, ""));
3676
+ }
3677
+ if (isNaN(num)) {
3678
+ throw new Error(
3679
+ "Invalid input: input must be a number or a numeric string."
3680
+ );
3681
+ }
3682
+ return num / 10;
3683
+ }
3684
+ var convertRialToToman_default = convertRialToToman;
3685
+
3686
+ // src/utils/getClaims.ts
3687
+ function getClaims(JWTToken) {
3688
+ const encodedClaims = JWTToken.split(".")[1];
3689
+ const decodedClaimsString = atob(encodedClaims);
3690
+ const claims = JSON.parse(decodedClaimsString);
3691
+ return claims;
3692
+ }
3693
+
3694
+ // src/utils/checkUser.ts
3695
+ function checkUser() {
3696
+ if (typeof window !== "undefined") {
3697
+ const hasToken = !!localStorage.getItem("auth_token");
3698
+ if (!hasToken) {
3699
+ localStorage.clear();
3700
+ window.location.href = "/auth/login";
3701
+ }
3702
+ }
3703
+ }
3704
+
3705
+ // src/utils/index.ts
3706
+ import { faIR } from "@mui/material/locale";
3707
+
3708
+ // src/utils/formatPersianNumber.ts
3709
+ function formatPersianNumber(num) {
3710
+ const n = typeof num === "string" ? Number(num.replace(/,/g, "")) : num;
3711
+ if (!Number.isFinite(n)) return "";
3712
+ const parts = [];
3713
+ const trillions = Math.floor(n / 1e12);
3714
+ if (trillions) {
3715
+ parts.push(`${trillions} \u062A\u0631\u06CC\u0644\u06CC\u0648\u0646`);
3716
+ }
3717
+ const billions = Math.floor(n % 1e12 / 1e9);
3718
+ if (billions) {
3719
+ parts.push(`${billions} \u0645\u06CC\u0644\u06CC\u0627\u0631\u062F`);
3720
+ }
3721
+ const millions = Math.floor(n % 1e9 / 1e6);
3722
+ if (millions) {
3723
+ parts.push(`${millions} \u0645\u06CC\u0644\u06CC\u0648\u0646`);
3724
+ }
3725
+ const thousands = Math.floor(n % 1e6 / 1e3);
3726
+ if (thousands) {
3727
+ if (thousands === 1) {
3728
+ parts.push(`\u0647\u0632\u0627\u0631`);
3729
+ } else {
3730
+ parts.push(`${thousands} \u0647\u0632\u0627\u0631`);
3731
+ }
3732
+ }
3733
+ const units = n % 1e3;
3734
+ units && parts.push(`${units}`);
3735
+ return parts.join(" \u0648 ");
3736
+ }
3737
+
3738
+ // src/utils/postToParent.ts
3739
+ var postToParent = (message) => {
3740
+ window.parent.postMessage(message, "*");
3741
+ };
3742
+ export {
3743
+ Accordion_default as Accordion,
3744
+ AccordionDetails_default as AccordionDetails,
3745
+ AccordionSummary_default as AccordionSummary,
3746
+ Autocomplete_default as Autocomplete,
3747
+ Box_default as Box,
3748
+ Button_default as Button,
3749
+ CardNumberInput_default as CardNumberInput,
3750
+ Checkbox_default as Checkbox,
3751
+ CircularProgress_default as CircularProgress,
3752
+ Container_default as Container,
3753
+ CounterBoxInput_default as CounterBoxInput,
3754
+ DataGrid_default as DataGrid,
3755
+ Dialog_default as Dialog,
3756
+ Divider_default as Divider,
3757
+ Drawer_default as Drawer,
3758
+ Fab_default as Fab,
3759
+ FormControl_default as FormControl,
3760
+ FormControlLabel_default as FormControlLabel,
3761
+ Grid_default as Grid,
3762
+ IconButton_default as IconButton,
3763
+ Image_default as Image,
3764
+ InputLabel_default as InputLabel,
3765
+ InputPhoneNumber_default as InputPhoneNumber,
3766
+ IosHiddenOtpInput_default as IosHiddenOtpInput,
3767
+ List_default as List,
3768
+ ListItem_default as ListItem,
3769
+ Loading_default as Loading,
3770
+ LoadingModal_default as LoadingModal,
3771
+ MenuItem_default as MenuItem,
3772
+ MessageProvider,
3773
+ MobileDatePicker_default as MobileDatePicker,
3774
+ Modal_default as Modal,
3775
+ MultiSelect_default as MultiSelect,
3776
+ NumberInput_default as NumberInput,
3777
+ OtpInput,
3778
+ Pagination_default as Pagination,
3779
+ ProgressBar_default as ProgressBar,
3780
+ Radio_default as Radio,
3781
+ RadioGroup_default as RadioGroup,
3782
+ SPAThemeProvider_default as SPAThemeProvider,
3783
+ Select_default as Select,
3784
+ Sentry,
3785
+ Skeleton_default as Skeleton,
3786
+ Slider_default as Slider,
3787
+ Step_default as Step,
3788
+ StepConnector_default as StepConnector,
3789
+ StepContent_default as StepContent,
3790
+ StepLabel_default as StepLabel,
3791
+ Stepper_default as Stepper,
3792
+ SvgIcon_default as SvgIcon,
3793
+ Tab_default as Tab,
3794
+ TextField_default as TextField,
3795
+ ThemeProvider_default as ThemeProvider,
3796
+ Toast_default as Toast,
3797
+ Toggle_default as Toggle,
3798
+ Typography_default as Typography,
3799
+ WheelDatePicker_default as WheelDatePicker,
3800
+ checkUser,
3801
+ convertRialToToman_default as convertRialToToman,
3802
+ faIR as coreFaIR,
3803
+ createApiRequest,
3804
+ createApiRequest as createApiRequestV2,
3805
+ createLogger,
3806
+ createQueryParams,
3807
+ defaultColors,
3808
+ delay,
3809
+ formatPersianNumber,
3810
+ getClaims,
3811
+ getPersianYMD,
3812
+ gregorianToJalali,
3813
+ initSentry,
3814
+ jalaliToDateUTC,
3815
+ jalaliToGregorian,
3816
+ longDateFormat,
3817
+ longFormatInWords,
3818
+ postToParent,
3819
+ shortDateFormat,
3820
+ MuiStepConnectorClasses as stepConnectorClasses,
3821
+ muiStyled as styled,
3822
+ toLatinDigits,
3823
+ useColorScheme,
3824
+ useErrorHandler,
3825
+ useLocalStorage,
3826
+ useMessage,
3827
+ useTheme2 as useTheme,
3828
+ useWebOtpListener,
3829
+ useWindowHeight,
3830
+ useWindowWidth
3831
+ };