warqadui 0.0.30 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -71,6 +71,7 @@ __export(index_exports, {
71
71
  ThemeToggle: () => ThemeToggle,
72
72
  WarqadProvider: () => WarqadProvider,
73
73
  generatePdf: () => generatePdf,
74
+ storage: () => storage,
74
75
  useA4StatementView: () => useA4DataView_default,
75
76
  useApi: () => useApis_default,
76
77
  useModal: () => useModal,
@@ -1156,6 +1157,14 @@ var Input = (0, import_react8.forwardRef)(
1156
1157
  const [showPassword, setShowPassword] = (0, import_react8.useState)(false);
1157
1158
  const { theme } = useWarqadConfig();
1158
1159
  const primaryColor = theme?.primaryColor;
1160
+ (0, import_react8.useEffect)(() => {
1161
+ if (form && name && props.value !== void 0 && props.value !== null && props.value !== "") {
1162
+ const currentFormValue = form.getValues(name);
1163
+ if (currentFormValue === void 0 || currentFormValue === "" || currentFormValue === 0) {
1164
+ form.setValue(name, props.value);
1165
+ }
1166
+ }
1167
+ }, [props.value, name, form]);
1159
1168
  let message = error;
1160
1169
  if (form && name) {
1161
1170
  const {
@@ -1238,39 +1247,62 @@ var Input = (0, import_react8.forwardRef)(
1238
1247
  {
1239
1248
  control: form.control,
1240
1249
  name,
1241
- render: ({ field: { onChange, value, ref: fieldRef, onBlur: onBlur2 } }) => renderInput(
1242
- {
1243
- ref: fieldRef,
1244
- onBlur: () => {
1245
- onBlur2();
1246
- },
1247
- value: value ? String(value).split(".").map(
1248
- (part, index) => index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
1249
- ).join(".") : "",
1250
- onChange: (e) => {
1251
- const rawValue = e.target.value.replace(/,/g, "");
1252
- if (!/^\d*\.?\d*$/.test(rawValue)) return;
1253
- if (rawValue === "") {
1254
- onChange("");
1255
- } else {
1256
- const numValue = Number(rawValue);
1257
- if (!isNaN(numValue) && String(numValue) === rawValue) {
1258
- onChange(numValue);
1250
+ render: ({ field: { onChange, value, ref: fieldRef, onBlur: onBlur2 } }) => {
1251
+ const hasValue = value !== void 0 && value !== null && value !== "";
1252
+ const hasPropsValue = props.value !== void 0 && props.value !== null && props.value !== "";
1253
+ const displayValue = hasValue ? value : hasPropsValue ? props.value : "";
1254
+ return renderInput(
1255
+ {
1256
+ ref: fieldRef,
1257
+ onBlur: () => {
1258
+ onBlur2();
1259
+ },
1260
+ value: displayValue !== "" ? String(displayValue).split(".").map(
1261
+ (part, index) => index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
1262
+ ).join(".") : "",
1263
+ onChange: (e) => {
1264
+ const rawValue = e.target.value.replace(/,/g, "");
1265
+ if (!/^\d*\.?\d*$/.test(rawValue)) return;
1266
+ if (rawValue === "") {
1267
+ onChange("");
1268
+ props.onChange?.("");
1259
1269
  } else {
1260
- onChange(rawValue);
1270
+ const numValue = Number(rawValue);
1271
+ if (!isNaN(numValue) && String(numValue) === rawValue) {
1272
+ onChange(numValue);
1273
+ props.onChange?.(numValue);
1274
+ } else {
1275
+ onChange(rawValue);
1276
+ props.onChange?.(rawValue);
1277
+ }
1261
1278
  }
1262
1279
  }
1263
- props.onChange?.(e);
1264
- }
1265
- },
1266
- "text"
1267
- )
1280
+ },
1281
+ "text"
1282
+ );
1283
+ }
1268
1284
  }
1269
1285
  );
1270
1286
  }
1271
- let inputPropsObj = form && name ? form.register(name, type === "number" ? { valueAsNumber: true } : {}) : {};
1287
+ let inputPropsObj = {};
1288
+ const originalOnChange = props.onChange;
1289
+ if (form && name) {
1290
+ const registeredProps = form.register(
1291
+ name,
1292
+ type === "number" ? { valueAsNumber: true } : {}
1293
+ );
1294
+ inputPropsObj = {
1295
+ ...registeredProps,
1296
+ onChange: (e) => {
1297
+ registeredProps.onChange(e);
1298
+ const rawValue = e.target.value.replace(/,/g, "");
1299
+ originalOnChange?.(
1300
+ type === "number" ? rawValue === "" ? "" : Number(rawValue) : e.target.value
1301
+ );
1302
+ }
1303
+ };
1304
+ }
1272
1305
  if (type === "number" && (!form || !name)) {
1273
- const originalOnChange = props.onChange;
1274
1306
  inputPropsObj = {
1275
1307
  ...inputPropsObj,
1276
1308
  value: props.value !== void 0 && props.value !== null ? String(props.value).split(".").map(
@@ -1280,20 +1312,20 @@ var Input = (0, import_react8.forwardRef)(
1280
1312
  const rawValue = e.target.value.replace(/,/g, "");
1281
1313
  if (!/^\d*\.?\d*$/.test(rawValue)) return;
1282
1314
  if (originalOnChange) {
1283
- const fakeEvent = {
1284
- ...e,
1285
- target: {
1286
- ...e.target,
1287
- value: rawValue,
1288
- valueAsNumber: rawValue === "" ? NaN : Number(rawValue)
1289
- }
1290
- };
1291
- originalOnChange(fakeEvent);
1315
+ originalOnChange(rawValue === "" ? "" : Number(rawValue));
1292
1316
  }
1293
1317
  }
1294
1318
  };
1295
1319
  return renderInput(inputPropsObj, "text");
1296
1320
  }
1321
+ if (!form || !name) {
1322
+ inputPropsObj = {
1323
+ ...inputPropsObj,
1324
+ onChange: (e) => {
1325
+ originalOnChange?.(e.target.value);
1326
+ }
1327
+ };
1328
+ }
1297
1329
  return renderInput(inputPropsObj, type === "number" ? "text" : type);
1298
1330
  }
1299
1331
  );
@@ -1411,6 +1443,14 @@ var useSelectContext = () => {
1411
1443
  };
1412
1444
  var Select = (0, import_react10.forwardRef)((props, ref) => {
1413
1445
  const { form, name, onChange, value, children, options = [] } = props;
1446
+ (0, import_react10.useEffect)(() => {
1447
+ if (form && name && value !== void 0 && value !== null && value !== "") {
1448
+ const currentFormValue = form.getValues(name);
1449
+ if (currentFormValue === void 0 || currentFormValue === "" || currentFormValue === 0) {
1450
+ form.setValue(name, value);
1451
+ }
1452
+ }
1453
+ }, [value, name, form]);
1414
1454
  if (form && name) {
1415
1455
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1416
1456
  import_react_hook_form3.Controller,
@@ -1865,30 +1905,47 @@ var Textarea = (0, import_react11.forwardRef)(
1865
1905
  ) }),
1866
1906
  message && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
1867
1907
  ] });
1908
+ (0, import_react11.useEffect)(() => {
1909
+ if (form && name && props.value !== void 0 && props.value !== null && props.value !== "") {
1910
+ const currentFormValue = form.getValues(name);
1911
+ if (currentFormValue === void 0 || currentFormValue === "" || currentFormValue === 0) {
1912
+ form.setValue(name, props.value);
1913
+ }
1914
+ }
1915
+ }, [props.value, name, form]);
1868
1916
  if (form && name) {
1869
1917
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1870
1918
  import_react_hook_form4.Controller,
1871
1919
  {
1872
1920
  control: form.control,
1873
1921
  name,
1874
- render: ({ field: { onChange, value, ref: fieldRef, onBlur: onBlur2 } }) => renderInput(
1875
- {
1876
- value: value || "",
1877
- // Ensure controlled input doesn't warn about uncontrolled
1878
- onChange: (e) => {
1879
- onChange(e);
1880
- props.onChange?.(e);
1922
+ render: ({ field: { onChange, value, ref: fieldRef, onBlur: onBlur2 } }) => {
1923
+ const displayValue = value !== void 0 && value !== null && value !== "" ? value : props.value;
1924
+ return renderInput(
1925
+ {
1926
+ value: displayValue || "",
1927
+ onChange: (e) => {
1928
+ onChange(e);
1929
+ props.onChange?.(e);
1930
+ },
1931
+ onBlur: () => {
1932
+ onBlur2();
1933
+ }
1881
1934
  },
1882
- onBlur: () => {
1883
- onBlur2();
1884
- }
1885
- },
1886
- fieldRef
1887
- )
1935
+ fieldRef
1936
+ );
1937
+ }
1888
1938
  }
1889
1939
  );
1890
1940
  }
1891
- return renderInput({}, ref);
1941
+ return renderInput(
1942
+ {
1943
+ onChange: (e) => {
1944
+ props.onChange?.(e);
1945
+ }
1946
+ },
1947
+ ref
1948
+ );
1892
1949
  }
1893
1950
  );
1894
1951
 
@@ -2080,6 +2137,14 @@ var useSearchApiContext = () => {
2080
2137
  var SearchApi = (0, import_react13.forwardRef)(
2081
2138
  (props, _) => {
2082
2139
  const { form, name, onChange, onSelect, onClear, value, children, ...restProps } = props;
2140
+ (0, import_react13.useEffect)(() => {
2141
+ if (form && name && value !== void 0 && value !== null && value !== "") {
2142
+ const currentFormValue = form.getValues(name);
2143
+ if (currentFormValue === void 0 || currentFormValue === "" || currentFormValue === 0) {
2144
+ form.setValue(name, value);
2145
+ }
2146
+ }
2147
+ }, [value, name, form]);
2083
2148
  if (form && name) {
2084
2149
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2085
2150
  import_react_hook_form5.Controller,
@@ -2208,12 +2273,12 @@ var SearchApiRoot = ({
2208
2273
  }
2209
2274
  }, [isOpen]);
2210
2275
  (0, import_react13.useEffect)(() => {
2211
- if (currentValue && !selectedObject) {
2276
+ if (currentValue !== void 0 && currentValue !== null && currentValue !== "" && !selectedObject) {
2212
2277
  setHasAttemptedHydration(false);
2213
2278
  fetchOptions(currentValue).finally(() => {
2214
2279
  setHasAttemptedHydration(true);
2215
2280
  });
2216
- } else if (!currentValue) {
2281
+ } else if (currentValue === void 0 || currentValue === null || currentValue === "") {
2217
2282
  setHasAttemptedHydration(true);
2218
2283
  if (selectedObject) setSelectedObject(void 0);
2219
2284
  }
@@ -2225,7 +2290,7 @@ var SearchApiRoot = ({
2225
2290
  return option[valueKey];
2226
2291
  };
2227
2292
  (0, import_react13.useEffect)(() => {
2228
- if (currentValue && !selectedObject && options.length > 0) {
2293
+ if (currentValue !== void 0 && currentValue !== null && currentValue !== "" && !selectedObject && options.length > 0) {
2229
2294
  const found = options.find((o) => getOptionValue(o) === currentValue);
2230
2295
  if (found) {
2231
2296
  setSelectedObject(found);
@@ -2278,13 +2343,13 @@ var SearchApiRoot = ({
2278
2343
  }, [fieldInternalProps]);
2279
2344
  const getDisplayValue = () => {
2280
2345
  if (selectedObject) return selectedObject[labelKey];
2281
- if (options.length > 0 && currentValue) {
2346
+ if (options.length > 0 && (currentValue !== void 0 && currentValue !== null && currentValue !== "")) {
2282
2347
  const found = options.find((o) => getOptionValue(o) === currentValue);
2283
2348
  if (found) return found[labelKey];
2284
2349
  }
2285
- if (isLoading || currentValue && !hasAttemptedHydration)
2350
+ if (isLoading || currentValue !== void 0 && currentValue !== null && currentValue !== "" && !hasAttemptedHydration)
2286
2351
  return "Loading...";
2287
- return currentValue || "";
2352
+ return currentValue !== void 0 && currentValue !== null && currentValue !== "" ? currentValue : "";
2288
2353
  };
2289
2354
  const handleSelect = (option) => {
2290
2355
  const val = getOptionValue(option);
@@ -2539,7 +2604,7 @@ var SearchApiInput = (0, import_react13.forwardRef)(
2539
2604
  }
2540
2605
  };
2541
2606
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
2542
- !isOpen && selectedValue && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0 flex items-center ms-1 truncate select-none", children: getDisplayValue() }),
2607
+ !isOpen && (selectedValue !== void 0 && selectedValue !== null && selectedValue !== "") && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0 flex items-center ms-1 truncate select-none", children: getDisplayValue() }),
2543
2608
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2544
2609
  "input",
2545
2610
  {
@@ -2851,7 +2916,8 @@ function DataTable({
2851
2916
  defaultExpanded = false,
2852
2917
  onChange,
2853
2918
  selectable = true,
2854
- filterables = true
2919
+ filterables = true,
2920
+ emptyState
2855
2921
  }) {
2856
2922
  const { theme } = useWarqadConfig();
2857
2923
  const primaryColor = theme?.primaryColor;
@@ -3079,7 +3145,7 @@ function DataTable({
3079
3145
  {
3080
3146
  colSpan: columns.length,
3081
3147
  className: "h-32 text-center text-sm text-gray-500",
3082
- children: "No results found."
3148
+ children: emptyState || "No results found."
3083
3149
  }
3084
3150
  ) }) }),
3085
3151
  table.getFooterGroups().some(
@@ -3145,6 +3211,85 @@ var import_react16 = __toESM(require("react"));
3145
3211
  var import_react_table2 = require("@tanstack/react-table");
3146
3212
  var import_lucide_react11 = require("lucide-react");
3147
3213
  var import_jsx_runtime24 = require("react/jsx-runtime");
3214
+ var TableCell = import_react16.default.memo(
3215
+ ({
3216
+ cell,
3217
+ rowPadding,
3218
+ verticalLines
3219
+ }) => {
3220
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3221
+ "td",
3222
+ {
3223
+ className: cn(
3224
+ rowPadding,
3225
+ "text-sm text-gray-700 dark:text-gray-200",
3226
+ verticalLines && "border-x border-gray-200 dark:border-zinc-800",
3227
+ cell.column.id === "_index" && "w-[1%] min-w-[40px] max-w-[40px] whitespace-nowrap",
3228
+ cell.column.columnDef.meta?.className
3229
+ ),
3230
+ style: {
3231
+ width: cell.column.columnDef.meta?.width ?? cell.column.getSize(),
3232
+ minWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.minSize,
3233
+ maxWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.maxSize
3234
+ },
3235
+ children: (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext())
3236
+ },
3237
+ cell.id
3238
+ );
3239
+ },
3240
+ (prev, next) => {
3241
+ return prev.cell.getValue() === next.cell.getValue() && prev.cell.row.getIsExpanded() === next.cell.row.getIsExpanded() && prev.cell.row.getIsSelected() === next.cell.row.getIsSelected() && prev.rowPadding === next.rowPadding && prev.verticalLines === next.verticalLines;
3242
+ }
3243
+ );
3244
+ var TableRow = import_react16.default.memo(
3245
+ ({
3246
+ row,
3247
+ rowPadding,
3248
+ verticalLines,
3249
+ renderSubComponent,
3250
+ hasSubComponent,
3251
+ columnsCount
3252
+ }) => {
3253
+ const isExpanded = row.getIsExpanded();
3254
+ const subComponentVisible = renderSubComponent && isExpanded && hasSubComponent(row.original);
3255
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react16.default.Fragment, { children: [
3256
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3257
+ "tr",
3258
+ {
3259
+ className: `border-b border-gray-200 dark:border-zinc-800 hover:bg-gray-50/50 dark:hover:bg-zinc-900/50 transition-colors last:border-b-0 ${renderSubComponent && hasSubComponent(row.original) ? "cursor-pointer" : ""}`,
3260
+ "data-state": row.getIsSelected() && "selected",
3261
+ onClick: (e) => {
3262
+ if (renderSubComponent && hasSubComponent(row.original)) {
3263
+ const target = e.target;
3264
+ if (!target.closest("button, a, input, select, textarea")) {
3265
+ row.toggleExpanded();
3266
+ }
3267
+ }
3268
+ },
3269
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3270
+ TableCell,
3271
+ {
3272
+ cell,
3273
+ rowPadding,
3274
+ verticalLines
3275
+ },
3276
+ cell.id
3277
+ ))
3278
+ }
3279
+ ),
3280
+ subComponentVisible && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tr", { className: "border-b border-gray-200 dark:border-zinc-800 bg-gray-50/20 dark:bg-zinc-900/20", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("td", { colSpan: columnsCount, className: "px-2 py-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "relative pl-6 pb-2 pr-2 pt-2 h-full", children: [
3281
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute left-2 top-0 bottom-2 w-6 border-l-2 border-b-2 rounded-bl-xl border-(--theme-primary) dark:border-(--theme-primary) pointer-events-none" }),
3282
+ renderSubComponent({
3283
+ row: row.original,
3284
+ index: row.index
3285
+ })
3286
+ ] }) }) })
3287
+ ] });
3288
+ },
3289
+ (prev, next) => {
3290
+ return prev.row.original === next.row.original && prev.row.getIsExpanded() === next.row.getIsExpanded() && prev.row.getIsSelected() === next.row.getIsSelected() && prev.rowPadding === next.rowPadding && prev.verticalLines === next.verticalLines;
3291
+ }
3292
+ );
3148
3293
  function PostTable({
3149
3294
  columns: userColumns,
3150
3295
  data: controlledData,
@@ -3158,7 +3303,8 @@ function PostTable({
3158
3303
  renderSubComponent,
3159
3304
  hasSubComponent = () => true,
3160
3305
  // default to true if renderSubComponent is provided
3161
- defaultExpanded = false
3306
+ defaultExpanded = false,
3307
+ submitLoading = false
3162
3308
  }) {
3163
3309
  const { theme } = useWarqadConfig();
3164
3310
  const primaryColor = theme?.primaryColor;
@@ -3206,18 +3352,46 @@ function PostTable({
3206
3352
  const [editingIndex, setEditingIndex] = (0, import_react16.useState)(null);
3207
3353
  const [isSavingAsync, setIsSavingAsync] = (0, import_react16.useState)(false);
3208
3354
  const [fieldErrors, setFieldErrors] = (0, import_react16.useState)({});
3209
- const handleSaveField = async () => {
3210
- if (Object.keys(entryData).length === 0) return;
3211
- let newData = [...data];
3212
- if (editingIndex !== null) {
3213
- newData[editingIndex] = {
3214
- ...newData[editingIndex],
3215
- ...entryData
3355
+ const latestStateRef = (0, import_react16.useRef)({
3356
+ data,
3357
+ entryData,
3358
+ editingIndex,
3359
+ isSavingAsync,
3360
+ submitLoading,
3361
+ fieldErrors,
3362
+ onChange
3363
+ });
3364
+ (0, import_react16.useEffect)(() => {
3365
+ latestStateRef.current = {
3366
+ data,
3367
+ entryData,
3368
+ editingIndex,
3369
+ isSavingAsync,
3370
+ submitLoading,
3371
+ fieldErrors,
3372
+ onChange
3373
+ };
3374
+ });
3375
+ const handleSaveField = (0, import_react16.useCallback)(async () => {
3376
+ const {
3377
+ data: data2,
3378
+ entryData: entryData2,
3379
+ editingIndex: editingIndex2,
3380
+ isSavingAsync: isSavingAsync2,
3381
+ submitLoading: submitLoading2,
3382
+ onChange: onChange2
3383
+ } = latestStateRef.current;
3384
+ if (Object.keys(entryData2).length === 0) return;
3385
+ let newData = [...data2];
3386
+ if (editingIndex2 !== null) {
3387
+ newData[editingIndex2] = {
3388
+ ...newData[editingIndex2],
3389
+ ...entryData2
3216
3390
  };
3217
3391
  } else {
3218
- newData = [...newData, entryData];
3392
+ newData = [...newData, entryData2];
3219
3393
  }
3220
- if (onChange) {
3394
+ if (onChange2) {
3221
3395
  setIsSavingAsync(true);
3222
3396
  try {
3223
3397
  const actions = {
@@ -3241,9 +3415,9 @@ function PostTable({
3241
3415
  }));
3242
3416
  }
3243
3417
  };
3244
- const type = editingIndex !== null ? "edit" : "add";
3245
- const result = await onChange({
3246
- entryData,
3418
+ const type = editingIndex2 !== null ? "edit" : "add";
3419
+ const result = await onChange2({
3420
+ entryData: entryData2,
3247
3421
  actions,
3248
3422
  actionType: type,
3249
3423
  fullData: newData
@@ -3261,83 +3435,93 @@ function PostTable({
3261
3435
  setEntryData({});
3262
3436
  setFieldErrors({});
3263
3437
  setIsSavingAsync(false);
3264
- if (editingIndex !== null) {
3438
+ if (editingIndex2 !== null) {
3265
3439
  setEditingIndex(null);
3266
3440
  } else {
3267
3441
  focusAndScrollEntryRow();
3268
3442
  }
3269
- };
3270
- const handleCancelEdit = () => {
3443
+ }, []);
3444
+ const handleCancelEdit = (0, import_react16.useCallback)(() => {
3271
3445
  setEditingIndex(null);
3272
3446
  setEntryData({});
3273
3447
  setFieldErrors({});
3274
- };
3275
- const handleEdit = (index2, rowOriginal) => {
3448
+ }, []);
3449
+ const handleEdit = (0, import_react16.useCallback)((index2, rowOriginal) => {
3276
3450
  setEditingIndex(index2);
3277
3451
  setEntryData(rowOriginal);
3278
- };
3279
- const handleDelete = (index2) => {
3280
- const newData = data.filter((_, i) => i !== index2);
3281
- setData(newData);
3282
- const actions = {
3283
- focus: (columnId) => {
3284
- if (entryRowRef.current) {
3285
- const td = entryRowRef.current.querySelector(
3286
- `td[data-column-id="${columnId}"]`
3287
- );
3288
- if (td) {
3289
- const input = td.querySelector(
3290
- `input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex='0'], [id*='${columnId}']`
3452
+ }, []);
3453
+ const handleDelete = (0, import_react16.useCallback)(
3454
+ (index2) => {
3455
+ const { data: data2, editingIndex: editingIndex2, onChange: onChange2 } = latestStateRef.current;
3456
+ const newData = data2.filter((_, i) => i !== index2);
3457
+ setData(newData);
3458
+ const actions = {
3459
+ focus: (columnId) => {
3460
+ if (entryRowRef.current) {
3461
+ const td = entryRowRef.current.querySelector(
3462
+ `td[data-column-id="${columnId}"]`
3291
3463
  );
3292
- if (input) input.focus();
3464
+ if (td) {
3465
+ const input = td.querySelector(
3466
+ `input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex='0'], [id*='${columnId}']`
3467
+ );
3468
+ if (input) input.focus();
3469
+ }
3293
3470
  }
3471
+ },
3472
+ setError: (columnId, error) => {
3473
+ setFieldErrors((prev) => ({
3474
+ ...prev,
3475
+ [columnId]: error
3476
+ }));
3294
3477
  }
3295
- },
3296
- setError: (columnId, error) => {
3297
- setFieldErrors((prev) => ({
3298
- ...prev,
3299
- [columnId]: error
3300
- }));
3478
+ };
3479
+ onChange2?.({
3480
+ entryData: data2[index2],
3481
+ actions,
3482
+ actionType: "delete",
3483
+ fullData: newData
3484
+ });
3485
+ if (editingIndex2 === index2) {
3486
+ handleCancelEdit();
3487
+ } else if (editingIndex2 !== null && editingIndex2 > index2) {
3488
+ setEditingIndex(editingIndex2 - 1);
3301
3489
  }
3302
- };
3303
- onChange?.({
3304
- entryData: data[index2],
3305
- actions,
3306
- actionType: "delete",
3307
- fullData: newData
3308
- });
3309
- if (editingIndex === index2) {
3310
- handleCancelEdit();
3311
- } else if (editingIndex !== null && editingIndex > index2) {
3312
- setEditingIndex(editingIndex - 1);
3313
- }
3314
- };
3315
- const actionColumn = {
3316
- id: "actions",
3317
- header: "Actions",
3318
- cell: ({ row }) => {
3319
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
3320
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3321
- "button",
3322
- {
3323
- onClick: () => handleEdit(row.index, row.original),
3324
- className: "p-1 px-2 rounded-md hover:bg-gray-100 dark:hover:bg-zinc-800 text-gray-500 hover:text-(--theme-primary) dark:hover:text-(--theme-primary) transition-colors",
3325
- title: "Edit",
3326
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Edit2, { size: 16 })
3327
- }
3328
- ),
3329
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3330
- "button",
3331
- {
3332
- onClick: () => handleDelete(row.index),
3333
- className: "p-1 px-2 rounded-md hover:bg-gray-100 dark:hover:bg-zinc-800 text-gray-500 hover:text-red-600 dark:hover:text-red-400 transition-colors",
3334
- title: "Delete",
3335
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Trash2, { size: 16 })
3336
- }
3337
- )
3338
- ] });
3339
- }
3340
- };
3490
+ },
3491
+ [handleCancelEdit]
3492
+ );
3493
+ const actionColumn = (0, import_react16.useMemo)(
3494
+ () => ({
3495
+ id: "actions",
3496
+ header: "Actions",
3497
+ cell: ({ row, table: table2 }) => {
3498
+ const { handleEdit: handleEdit2, handleDelete: handleDelete2, submitLoading: submitLoading2, isSavingAsync: isSavingAsync2 } = table2.options.meta;
3499
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
3500
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3501
+ "button",
3502
+ {
3503
+ onClick: () => handleEdit2(row.index, row.original),
3504
+ disabled: submitLoading2 || isSavingAsync2,
3505
+ className: "p-1 px-2 rounded-md hover:bg-gray-100 dark:hover:bg-zinc-800 text-gray-500 hover:text-(--theme-primary) dark:hover:text-(--theme-primary) transition-colors disabled:opacity-50",
3506
+ title: "Edit",
3507
+ children: submitLoading2 || isSavingAsync2 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Loader2, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Edit2, { size: 16 })
3508
+ }
3509
+ ),
3510
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3511
+ "button",
3512
+ {
3513
+ onClick: () => handleDelete2(row.index),
3514
+ disabled: submitLoading2 || isSavingAsync2,
3515
+ className: "p-1 px-2 rounded-md hover:bg-gray-100 dark:hover:bg-zinc-800 text-gray-500 hover:text-red-600 dark:hover:text-red-400 transition-colors disabled:opacity-50",
3516
+ title: "Delete",
3517
+ children: submitLoading2 || isSavingAsync2 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Loader2, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Trash2, { size: 16 })
3518
+ }
3519
+ )
3520
+ ] });
3521
+ }
3522
+ }),
3523
+ []
3524
+ );
3341
3525
  const columns = (0, import_react16.useMemo)(() => {
3342
3526
  const mappedUserColumns = userColumns.map((col) => ({
3343
3527
  ...col,
@@ -3386,6 +3570,12 @@ function PostTable({
3386
3570
  columnFilters,
3387
3571
  columnVisibility,
3388
3572
  expanded
3573
+ },
3574
+ meta: {
3575
+ handleEdit,
3576
+ handleDelete,
3577
+ submitLoading,
3578
+ isSavingAsync
3389
3579
  }
3390
3580
  });
3391
3581
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
@@ -3440,54 +3630,18 @@ function PostTable({
3440
3630
  ))
3441
3631
  },
3442
3632
  `skeleton-${i}`
3443
- )) : table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react16.default.Fragment, { children: [
3444
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3445
- "tr",
3446
- {
3447
- className: `border-b border-gray-200 dark:border-zinc-800 hover:bg-gray-50/50 dark:hover:bg-zinc-900/50 transition-colors last:border-b-0 ${renderSubComponent && hasSubComponent(row.original) ? "cursor-pointer" : ""}`,
3448
- "data-state": row.getIsSelected() && "selected",
3449
- onClick: (e) => {
3450
- if (renderSubComponent && hasSubComponent(row.original)) {
3451
- const target = e.target;
3452
- if (!target.closest(
3453
- "button, a, input, select, textarea"
3454
- )) {
3455
- row.toggleExpanded();
3456
- }
3457
- }
3458
- },
3459
- children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3460
- "td",
3461
- {
3462
- className: cn(
3463
- rowPadding,
3464
- "text-sm text-gray-700 dark:text-gray-200",
3465
- verticalLines && "border-x border-gray-200 dark:border-zinc-800",
3466
- cell.column.id === "_index" && "w-[1%] min-w-[40px] max-w-[40px] whitespace-nowrap",
3467
- cell.column.columnDef.meta?.className
3468
- ),
3469
- style: {
3470
- width: cell.column.columnDef.meta?.width ?? cell.column.getSize(),
3471
- minWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.minSize,
3472
- maxWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.maxSize
3473
- },
3474
- children: (0, import_react_table2.flexRender)(
3475
- cell.column.columnDef.cell,
3476
- cell.getContext()
3477
- )
3478
- },
3479
- cell.id
3480
- ))
3481
- }
3482
- ),
3483
- renderSubComponent && row.getIsExpanded() && hasSubComponent(row.original) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tr", { className: "border-b border-gray-200 dark:border-zinc-800 bg-gray-50/20 dark:bg-zinc-900/20", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("td", { colSpan: columns.length, className: "px-2 py-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "relative pl-6 pb-2 pr-2 pt-2 h-full", children: [
3484
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "absolute left-2 top-0 bottom-2 w-6 border-l-2 border-b-2 rounded-bl-xl border-(--theme-primary) dark:border-(--theme-primary) pointer-events-none" }),
3485
- renderSubComponent({
3486
- row: row.original,
3487
- index: row.index
3488
- })
3489
- ] }) }) })
3490
- ] }, row.id)) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3633
+ )) : table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3634
+ TableRow,
3635
+ {
3636
+ row,
3637
+ rowPadding,
3638
+ verticalLines,
3639
+ renderSubComponent,
3640
+ hasSubComponent,
3641
+ columnsCount: columns.length
3642
+ },
3643
+ row.id
3644
+ )) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3491
3645
  "td",
3492
3646
  {
3493
3647
  colSpan: columns.length,
@@ -3523,17 +3677,23 @@ function PostTable({
3523
3677
  "button",
3524
3678
  {
3525
3679
  onClick: handleSaveField,
3526
- disabled: isSavingAsync,
3680
+ disabled: isSavingAsync || submitLoading,
3527
3681
  className: "flex-1 h-8 flex items-center justify-center rounded-lg bg-green-500/10 text-green-600 dark:bg-emerald-500/20 dark:text-emerald-400 hover:bg-green-500 hover:text-white dark:hover:bg-emerald-500 transition-colors shadow-sm active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed",
3528
3682
  title: "Update",
3529
- children: isSavingAsync ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-3.5 h-3.5 rounded-full border-2 border-emerald-500/30 border-t-emerald-500 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Check, { size: 16, strokeWidth: 2.5 })
3683
+ children: isSavingAsync || submitLoading ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3684
+ import_lucide_react11.Loader2,
3685
+ {
3686
+ size: 16,
3687
+ className: "animate-spin"
3688
+ }
3689
+ ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Check, { size: 16, strokeWidth: 2.5 })
3530
3690
  }
3531
3691
  ),
3532
3692
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3533
3693
  "button",
3534
3694
  {
3535
3695
  onClick: handleCancelEdit,
3536
- disabled: isSavingAsync,
3696
+ disabled: isSavingAsync || submitLoading,
3537
3697
  className: "flex-1 h-8 flex items-center justify-center rounded-lg bg-red-500/10 text-red-600 dark:bg-red-500/20 dark:text-red-400 hover:bg-red-500 hover:text-white dark:hover:bg-red-500 transition-colors shadow-sm active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed",
3538
3698
  title: "Cancel",
3539
3699
  children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.X, { size: 16, strokeWidth: 2.5 })
@@ -3547,15 +3707,21 @@ function PostTable({
3547
3707
  "button",
3548
3708
  {
3549
3709
  onClick: handleSaveField,
3550
- disabled: isSavingAsync,
3710
+ disabled: isSavingAsync || submitLoading,
3551
3711
  className: "w-full cursor-pointer h-8 flex items-center justify-center gap-1.5 rounded-lg text-white text-xs font-medium transition-all shadow-sm hover:shadow-md hover:-translate-y-px active:scale-95 active:translate-y-0 hover:brightness-110 disabled:opacity-50 disabled:cursor-not-allowed",
3552
3712
  style: {
3553
3713
  backgroundColor: "var(--theme-primary)"
3554
3714
  },
3555
3715
  title: "Add Row",
3556
3716
  children: [
3557
- isSavingAsync ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-3.5 h-3.5 rounded-full border-2 border-white/30 border-t-white animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Plus, { size: 14, strokeWidth: 2.5 }),
3558
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: isSavingAsync ? "Adding..." : "Add" })
3717
+ isSavingAsync || submitLoading ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3718
+ import_lucide_react11.Loader2,
3719
+ {
3720
+ size: 14,
3721
+ className: "animate-spin"
3722
+ }
3723
+ ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Plus, { size: 14, strokeWidth: 2.5 }),
3724
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: isSavingAsync || submitLoading ? "Adding..." : "Add" })
3559
3725
  ]
3560
3726
  }
3561
3727
  ) }) })
@@ -3708,7 +3874,8 @@ function SimpleTable({
3708
3874
  startIndex = 0,
3709
3875
  isLoading = false,
3710
3876
  title,
3711
- enableSearch = false
3877
+ enableSearch = false,
3878
+ emptyState
3712
3879
  }) {
3713
3880
  const columns = (0, import_react17.useMemo)(() => {
3714
3881
  const cols = userColumns.filter((col) => !col.hide).map((col) => ({
@@ -3790,8 +3957,8 @@ function SimpleTable({
3790
3957
  "td",
3791
3958
  {
3792
3959
  colSpan: columns.length,
3793
- className: "text-center py-8 text-gray-500 font-medium",
3794
- children: "No transactions found."
3960
+ className: "text-center text-gray-500 font-medium",
3961
+ children: emptyState || /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "py-8", children: "No transactions found." })
3795
3962
  }
3796
3963
  ) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3797
3964
  "tr",
@@ -4064,24 +4231,22 @@ var useA4StatementView = ({
4064
4231
  }
4065
4232
  );
4066
4233
  const DisplayInfoGridEl = Array.isArray(info) && info.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { id: "a4-info-grid", className: "px-8", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(InfoGrid, { className: "mb-4", items: info, isLoading }) }) : null;
4067
- if (!isLoading && (error || !data || data.length === 0)) {
4068
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex flex-col relative w-full items-center justify-center p-8 min-h-96", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col items-center justify-center p-12 bg-gray-50/50 dark:bg-zinc-900/30 rounded-2xl border border-dashed border-gray-300 dark:border-zinc-700 w-full max-w-xl text-center shadow-sm", children: [
4069
- error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-16 h-16 bg-red-100 dark:bg-red-500/10 rounded-full flex items-center justify-center mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react12.AlertCircle, { className: "w-8 h-8 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-16 h-16 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react12.FileX, { className: "w-8 h-8 text-gray-500 dark:text-gray-400" }) }),
4070
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h3", { className: "text-xl font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Statement" : "No Records Found" }),
4071
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm text-gray-500 dark:text-gray-400 max-w-xs mb-8 leading-relaxed", children: error ? typeof error === "string" ? error : "An unexpected error occurred while fetching the statement data." : "There are no transactions or records available in this requested statement." }),
4072
- url && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
4073
- "button",
4074
- {
4075
- onClick: () => get({ url, v, params, delay }),
4076
- className: "flex items-center gap-2 px-6 py-2.5 bg-black dark:bg-white text-white dark:text-black font-semibold rounded-lg shadow-md hover:bg-gray-800 dark:hover:bg-gray-100 transition-all active:scale-95",
4077
- children: [
4078
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react12.RefreshCw, { size: 16 }),
4079
- "Try Again"
4080
- ]
4081
- }
4082
- )
4083
- ] }) });
4084
- }
4234
+ const emptyState = !isLoading && (error || !data || data.length === 0) ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex flex-col relative w-full items-center justify-center py-12 min-h-[300px]", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col items-center justify-center p-8 bg-gray-50/50 dark:bg-zinc-900/30 rounded-2xl border border-dashed border-gray-300 dark:border-zinc-700 w-full max-w-lg text-center shadow-sm", children: [
4235
+ error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-14 h-14 bg-red-100 dark:bg-red-500/10 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react12.AlertCircle, { className: "w-7 h-7 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-14 h-14 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react12.FileX, { className: "w-7 h-7 text-gray-500 dark:text-gray-400" }) }),
4236
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h3", { className: "text-lg font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Statement" : "No Records Found" }),
4237
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm text-gray-500 dark:text-gray-400 max-w-xs mb-6 leading-relaxed", children: error ? typeof error === "string" ? error : "An unexpected error occurred while fetching the statement data." : "There are no transactions or records available in this requested statement." }),
4238
+ url && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
4239
+ "button",
4240
+ {
4241
+ onClick: () => get({ url, v, params, delay }),
4242
+ className: "flex items-center gap-2 px-5 py-2 bg-black dark:bg-white text-white dark:text-black font-semibold rounded-lg shadow-md hover:bg-gray-800 dark:hover:bg-gray-100 transition-all active:scale-95 text-sm",
4243
+ children: [
4244
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react12.RefreshCw, { size: 14 }),
4245
+ "Try Again"
4246
+ ]
4247
+ }
4248
+ )
4249
+ ] }) }) : void 0;
4085
4250
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col relative w-full items-center", children: [
4086
4251
  isMeasuring && filteredDisplayData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "absolute top-0 opacity-0 pointer-events-none -left-full", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4087
4252
  "div",
@@ -4176,7 +4341,7 @@ var useA4StatementView = ({
4176
4341
  ] }),
4177
4342
  pageIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "hidden print:flex mb-4 border-b border-gray-200 print:border-gray-200 pb-2 items-center gap-2 justify-between px-2 mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h3", { className: "text-sm font-bold text-gray-800 print:text-gray-800 uppercase tracking-wide shrink-0", children: "Recent Transactions" }) }),
4178
4343
  pageIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "h-5 print:h-0" }),
4179
- (pageData.length > 0 || isLoading) && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4344
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4180
4345
  SimpleTable,
4181
4346
  {
4182
4347
  columns,
@@ -4186,6 +4351,7 @@ var useA4StatementView = ({
4186
4351
  index,
4187
4352
  startIndex: pages.slice(0, pageIndex).reduce((acc, curr) => acc + curr.length, 0),
4188
4353
  verticalLines,
4354
+ emptyState,
4189
4355
  isLoading: isLoading || isMeasuring && pages.length === 1 && pages[0].length === 0
4190
4356
  }
4191
4357
  ),
@@ -4267,30 +4433,28 @@ var useTransaction = ({
4267
4433
  createTitle = "Add New",
4268
4434
  ...rest
4269
4435
  }) => {
4270
- if (!isLoading && (error || !data || data.length === 0)) {
4271
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4272
- "div",
4273
- {
4274
- className: `flex flex-col relative w-full items-center justify-center p-8 min-h-96 ${className}`,
4275
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col items-center justify-center p-12 bg-gray-50/50 dark:bg-zinc-900/30 rounded-2xl border border-dashed border-gray-300 dark:border-zinc-700 w-full max-w-xl text-center shadow-sm", children: [
4276
- error ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-16 h-16 bg-red-100 dark:bg-red-500/10 rounded-full flex items-center justify-center mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.AlertCircle, { className: "w-8 h-8 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-16 h-16 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.FileX, { className: "w-8 h-8 text-gray-500 dark:text-gray-400" }) }),
4277
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h3", { className: "text-xl font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Data" : "No Records Found" }),
4278
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-sm text-gray-500 dark:text-gray-400 max-w-xs mb-8 leading-relaxed", children: error ? typeof error === "string" ? error : "An unexpected error occurred while fetching the data." : "There are no transactions or records available to display here." }),
4279
- url && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4280
- "button",
4281
- {
4282
- onClick: () => get({ url, v, params, delay }),
4283
- className: "flex items-center gap-2 px-6 py-2.5 bg-black dark:bg-white text-white dark:text-black font-semibold rounded-lg shadow-md hover:bg-gray-800 dark:hover:bg-gray-100 transition-all active:scale-95",
4284
- children: [
4285
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.RefreshCw, { size: 16 }),
4286
- "Try Again"
4287
- ]
4288
- }
4289
- )
4290
- ] })
4291
- }
4292
- );
4293
- }
4436
+ const emptyState = !isLoading && (error || !data || data.length === 0) ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4437
+ "div",
4438
+ {
4439
+ className: `flex flex-col relative w-full items-center justify-center py-12 min-h-[300px] ${className}`,
4440
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col items-center justify-center p-8 bg-gray-50/50 dark:bg-zinc-900/30 rounded-2xl border border-dashed border-gray-300 dark:border-zinc-700 w-full max-w-lg text-center shadow-sm", children: [
4441
+ error ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-14 h-14 bg-red-100 dark:bg-red-500/10 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.AlertCircle, { className: "w-7 h-7 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-14 h-14 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.FileX, { className: "w-7 h-7 text-gray-500 dark:text-gray-400" }) }),
4442
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h3", { className: "text-lg font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Data" : "No Records Found" }),
4443
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-sm text-gray-500 dark:text-gray-400 max-w-xs mb-6 leading-relaxed", children: error ? typeof error === "string" ? error : "An unexpected error occurred while fetching the data." : "There are no transactions or records available to display here." }),
4444
+ url && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4445
+ "button",
4446
+ {
4447
+ onClick: () => get({ url, v, params, delay }),
4448
+ className: "flex items-center gap-2 px-5 py-2 bg-black dark:bg-white text-white dark:text-black font-semibold rounded-lg shadow-md hover:bg-gray-800 dark:hover:bg-gray-100 transition-all active:scale-95 text-sm",
4449
+ children: [
4450
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.RefreshCw, { size: 14 }),
4451
+ "Try Again"
4452
+ ]
4453
+ }
4454
+ )
4455
+ ] })
4456
+ }
4457
+ ) : void 0;
4294
4458
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Card, { children: [
4295
4459
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Card.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "flex items-center justify-between gap-4 py-2", children: [
4296
4460
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "space-y-1", children: [
@@ -4334,6 +4498,7 @@ var useTransaction = ({
4334
4498
  verticalLines,
4335
4499
  index,
4336
4500
  rowPadding,
4501
+ emptyState,
4337
4502
  ...rest
4338
4503
  }
4339
4504
  ) }) })
@@ -4475,6 +4640,66 @@ var generatePdf = async (elementId, options = {}) => {
4475
4640
  throw error;
4476
4641
  }
4477
4642
  };
4643
+
4644
+ // src/utils/storage.ts
4645
+ var isBrowser = typeof window !== "undefined" && typeof localStorage !== "undefined";
4646
+ var storage = {
4647
+ set(key, value) {
4648
+ if (!isBrowser) return;
4649
+ try {
4650
+ localStorage.setItem(key, JSON.stringify(value));
4651
+ } catch (error) {
4652
+ console.error(`[storage] Error saving key "${key}":`, error);
4653
+ }
4654
+ },
4655
+ get(key) {
4656
+ if (!isBrowser) return key ? null : {};
4657
+ if (key !== void 0) {
4658
+ try {
4659
+ const item = localStorage.getItem(key);
4660
+ if (item === null) return null;
4661
+ return JSON.parse(item);
4662
+ } catch (error) {
4663
+ const rawValue = localStorage.getItem(key);
4664
+ return rawValue;
4665
+ }
4666
+ }
4667
+ const allItems = {};
4668
+ for (let i = 0; i < localStorage.length; i++) {
4669
+ const k = localStorage.key(i);
4670
+ if (k) {
4671
+ const value = localStorage.getItem(k);
4672
+ try {
4673
+ allItems[k] = value ? JSON.parse(value) : null;
4674
+ } catch {
4675
+ allItems[k] = value;
4676
+ }
4677
+ }
4678
+ }
4679
+ return allItems;
4680
+ },
4681
+ remove(key) {
4682
+ if (!isBrowser) return;
4683
+ localStorage.removeItem(key);
4684
+ },
4685
+ clear() {
4686
+ if (!isBrowser) return;
4687
+ localStorage.clear();
4688
+ },
4689
+ has(key) {
4690
+ if (!isBrowser) return false;
4691
+ return localStorage.getItem(key) !== null;
4692
+ },
4693
+ keys() {
4694
+ if (!isBrowser) return [];
4695
+ const keys = [];
4696
+ for (let i = 0; i < localStorage.length; i++) {
4697
+ const key = localStorage.key(i);
4698
+ if (key) keys.push(key);
4699
+ }
4700
+ return keys;
4701
+ }
4702
+ };
4478
4703
  // Annotate the CommonJS export names for ESM import in node:
4479
4704
  0 && (module.exports = {
4480
4705
  A4DataView,
@@ -4518,6 +4743,7 @@ var generatePdf = async (elementId, options = {}) => {
4518
4743
  ThemeToggle,
4519
4744
  WarqadProvider,
4520
4745
  generatePdf,
4746
+ storage,
4521
4747
  useA4StatementView,
4522
4748
  useApi,
4523
4749
  useModal,