warqadui 0.0.30 → 0.0.31

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.mjs CHANGED
@@ -2802,7 +2802,8 @@ function DataTable({
2802
2802
  defaultExpanded = false,
2803
2803
  onChange,
2804
2804
  selectable = true,
2805
- filterables = true
2805
+ filterables = true,
2806
+ emptyState
2806
2807
  }) {
2807
2808
  const { theme } = useWarqadConfig();
2808
2809
  const primaryColor = theme?.primaryColor;
@@ -3030,7 +3031,7 @@ function DataTable({
3030
3031
  {
3031
3032
  colSpan: columns.length,
3032
3033
  className: "h-32 text-center text-sm text-gray-500",
3033
- children: "No results found."
3034
+ children: emptyState || "No results found."
3034
3035
  }
3035
3036
  ) }) }),
3036
3037
  table.getFooterGroups().some(
@@ -3092,7 +3093,7 @@ function DataTable({
3092
3093
  }
3093
3094
 
3094
3095
  // src/components/tables/PostTable.tsx
3095
- import React9, { useState as useState15, useMemo as useMemo4, useEffect as useEffect9, useRef as useRef5 } from "react";
3096
+ import React9, { useState as useState15, useMemo as useMemo4, useEffect as useEffect9, useRef as useRef5, useCallback as useCallback2 } from "react";
3096
3097
  import {
3097
3098
  useReactTable as useReactTable2,
3098
3099
  getCoreRowModel as getCoreRowModel2,
@@ -3101,8 +3102,87 @@ import {
3101
3102
  getExpandedRowModel as getExpandedRowModel2,
3102
3103
  flexRender as flexRender2
3103
3104
  } from "@tanstack/react-table";
3104
- import { Plus, Edit2, Trash2, Check as Check4, X as X3, ChevronDown as ChevronDown5 } from "lucide-react";
3105
+ import { Plus, Edit2, Trash2, Check as Check4, X as X3, ChevronDown as ChevronDown5, Loader2 as Loader23 } from "lucide-react";
3105
3106
  import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
3107
+ var TableCell = React9.memo(
3108
+ ({
3109
+ cell,
3110
+ rowPadding,
3111
+ verticalLines
3112
+ }) => {
3113
+ return /* @__PURE__ */ jsx24(
3114
+ "td",
3115
+ {
3116
+ className: cn(
3117
+ rowPadding,
3118
+ "text-sm text-gray-700 dark:text-gray-200",
3119
+ verticalLines && "border-x border-gray-200 dark:border-zinc-800",
3120
+ cell.column.id === "_index" && "w-[1%] min-w-[40px] max-w-[40px] whitespace-nowrap",
3121
+ cell.column.columnDef.meta?.className
3122
+ ),
3123
+ style: {
3124
+ width: cell.column.columnDef.meta?.width ?? cell.column.getSize(),
3125
+ minWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.minSize,
3126
+ maxWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.maxSize
3127
+ },
3128
+ children: flexRender2(cell.column.columnDef.cell, cell.getContext())
3129
+ },
3130
+ cell.id
3131
+ );
3132
+ },
3133
+ (prev, next) => {
3134
+ 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;
3135
+ }
3136
+ );
3137
+ var TableRow = React9.memo(
3138
+ ({
3139
+ row,
3140
+ rowPadding,
3141
+ verticalLines,
3142
+ renderSubComponent,
3143
+ hasSubComponent,
3144
+ columnsCount
3145
+ }) => {
3146
+ const isExpanded = row.getIsExpanded();
3147
+ const subComponentVisible = renderSubComponent && isExpanded && hasSubComponent(row.original);
3148
+ return /* @__PURE__ */ jsxs18(React9.Fragment, { children: [
3149
+ /* @__PURE__ */ jsx24(
3150
+ "tr",
3151
+ {
3152
+ 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" : ""}`,
3153
+ "data-state": row.getIsSelected() && "selected",
3154
+ onClick: (e) => {
3155
+ if (renderSubComponent && hasSubComponent(row.original)) {
3156
+ const target = e.target;
3157
+ if (!target.closest("button, a, input, select, textarea")) {
3158
+ row.toggleExpanded();
3159
+ }
3160
+ }
3161
+ },
3162
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx24(
3163
+ TableCell,
3164
+ {
3165
+ cell,
3166
+ rowPadding,
3167
+ verticalLines
3168
+ },
3169
+ cell.id
3170
+ ))
3171
+ }
3172
+ ),
3173
+ subComponentVisible && /* @__PURE__ */ jsx24("tr", { className: "border-b border-gray-200 dark:border-zinc-800 bg-gray-50/20 dark:bg-zinc-900/20", children: /* @__PURE__ */ jsx24("td", { colSpan: columnsCount, className: "px-2 py-0", children: /* @__PURE__ */ jsxs18("div", { className: "relative pl-6 pb-2 pr-2 pt-2 h-full", children: [
3174
+ /* @__PURE__ */ jsx24("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" }),
3175
+ renderSubComponent({
3176
+ row: row.original,
3177
+ index: row.index
3178
+ })
3179
+ ] }) }) })
3180
+ ] });
3181
+ },
3182
+ (prev, next) => {
3183
+ 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;
3184
+ }
3185
+ );
3106
3186
  function PostTable({
3107
3187
  columns: userColumns,
3108
3188
  data: controlledData,
@@ -3116,7 +3196,8 @@ function PostTable({
3116
3196
  renderSubComponent,
3117
3197
  hasSubComponent = () => true,
3118
3198
  // default to true if renderSubComponent is provided
3119
- defaultExpanded = false
3199
+ defaultExpanded = false,
3200
+ submitLoading = false
3120
3201
  }) {
3121
3202
  const { theme } = useWarqadConfig();
3122
3203
  const primaryColor = theme?.primaryColor;
@@ -3164,18 +3245,46 @@ function PostTable({
3164
3245
  const [editingIndex, setEditingIndex] = useState15(null);
3165
3246
  const [isSavingAsync, setIsSavingAsync] = useState15(false);
3166
3247
  const [fieldErrors, setFieldErrors] = useState15({});
3167
- const handleSaveField = async () => {
3168
- if (Object.keys(entryData).length === 0) return;
3169
- let newData = [...data];
3170
- if (editingIndex !== null) {
3171
- newData[editingIndex] = {
3172
- ...newData[editingIndex],
3173
- ...entryData
3248
+ const latestStateRef = useRef5({
3249
+ data,
3250
+ entryData,
3251
+ editingIndex,
3252
+ isSavingAsync,
3253
+ submitLoading,
3254
+ fieldErrors,
3255
+ onChange
3256
+ });
3257
+ useEffect9(() => {
3258
+ latestStateRef.current = {
3259
+ data,
3260
+ entryData,
3261
+ editingIndex,
3262
+ isSavingAsync,
3263
+ submitLoading,
3264
+ fieldErrors,
3265
+ onChange
3266
+ };
3267
+ });
3268
+ const handleSaveField = useCallback2(async () => {
3269
+ const {
3270
+ data: data2,
3271
+ entryData: entryData2,
3272
+ editingIndex: editingIndex2,
3273
+ isSavingAsync: isSavingAsync2,
3274
+ submitLoading: submitLoading2,
3275
+ onChange: onChange2
3276
+ } = latestStateRef.current;
3277
+ if (Object.keys(entryData2).length === 0) return;
3278
+ let newData = [...data2];
3279
+ if (editingIndex2 !== null) {
3280
+ newData[editingIndex2] = {
3281
+ ...newData[editingIndex2],
3282
+ ...entryData2
3174
3283
  };
3175
3284
  } else {
3176
- newData = [...newData, entryData];
3285
+ newData = [...newData, entryData2];
3177
3286
  }
3178
- if (onChange) {
3287
+ if (onChange2) {
3179
3288
  setIsSavingAsync(true);
3180
3289
  try {
3181
3290
  const actions = {
@@ -3199,9 +3308,9 @@ function PostTable({
3199
3308
  }));
3200
3309
  }
3201
3310
  };
3202
- const type = editingIndex !== null ? "edit" : "add";
3203
- const result = await onChange({
3204
- entryData,
3311
+ const type = editingIndex2 !== null ? "edit" : "add";
3312
+ const result = await onChange2({
3313
+ entryData: entryData2,
3205
3314
  actions,
3206
3315
  actionType: type,
3207
3316
  fullData: newData
@@ -3219,23 +3328,24 @@ function PostTable({
3219
3328
  setEntryData({});
3220
3329
  setFieldErrors({});
3221
3330
  setIsSavingAsync(false);
3222
- if (editingIndex !== null) {
3331
+ if (editingIndex2 !== null) {
3223
3332
  setEditingIndex(null);
3224
3333
  } else {
3225
3334
  focusAndScrollEntryRow();
3226
3335
  }
3227
- };
3228
- const handleCancelEdit = () => {
3336
+ }, []);
3337
+ const handleCancelEdit = useCallback2(() => {
3229
3338
  setEditingIndex(null);
3230
3339
  setEntryData({});
3231
3340
  setFieldErrors({});
3232
- };
3233
- const handleEdit = (index2, rowOriginal) => {
3341
+ }, []);
3342
+ const handleEdit = useCallback2((index2, rowOriginal) => {
3234
3343
  setEditingIndex(index2);
3235
3344
  setEntryData(rowOriginal);
3236
- };
3237
- const handleDelete = (index2) => {
3238
- const newData = data.filter((_, i) => i !== index2);
3345
+ }, []);
3346
+ const handleDelete = useCallback2((index2) => {
3347
+ const { data: data2, editingIndex: editingIndex2, onChange: onChange2 } = latestStateRef.current;
3348
+ const newData = data2.filter((_, i) => i !== index2);
3239
3349
  setData(newData);
3240
3350
  const actions = {
3241
3351
  focus: (columnId) => {
@@ -3258,44 +3368,47 @@ function PostTable({
3258
3368
  }));
3259
3369
  }
3260
3370
  };
3261
- onChange?.({
3262
- entryData: data[index2],
3371
+ onChange2?.({
3372
+ entryData: data2[index2],
3263
3373
  actions,
3264
3374
  actionType: "delete",
3265
3375
  fullData: newData
3266
3376
  });
3267
- if (editingIndex === index2) {
3377
+ if (editingIndex2 === index2) {
3268
3378
  handleCancelEdit();
3269
- } else if (editingIndex !== null && editingIndex > index2) {
3270
- setEditingIndex(editingIndex - 1);
3379
+ } else if (editingIndex2 !== null && editingIndex2 > index2) {
3380
+ setEditingIndex(editingIndex2 - 1);
3271
3381
  }
3272
- };
3273
- const actionColumn = {
3382
+ }, [handleCancelEdit]);
3383
+ const actionColumn = useMemo4(() => ({
3274
3384
  id: "actions",
3275
3385
  header: "Actions",
3276
- cell: ({ row }) => {
3386
+ cell: ({ row, table: table2 }) => {
3387
+ const { handleEdit: handleEdit2, handleDelete: handleDelete2, submitLoading: submitLoading2, isSavingAsync: isSavingAsync2 } = table2.options.meta;
3277
3388
  return /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
3278
3389
  /* @__PURE__ */ jsx24(
3279
3390
  "button",
3280
3391
  {
3281
- onClick: () => handleEdit(row.index, row.original),
3282
- 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",
3392
+ onClick: () => handleEdit2(row.index, row.original),
3393
+ disabled: submitLoading2 || isSavingAsync2,
3394
+ 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",
3283
3395
  title: "Edit",
3284
- children: /* @__PURE__ */ jsx24(Edit2, { size: 16 })
3396
+ children: submitLoading2 || isSavingAsync2 ? /* @__PURE__ */ jsx24(Loader23, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Edit2, { size: 16 })
3285
3397
  }
3286
3398
  ),
3287
3399
  /* @__PURE__ */ jsx24(
3288
3400
  "button",
3289
3401
  {
3290
- onClick: () => handleDelete(row.index),
3291
- 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",
3402
+ onClick: () => handleDelete2(row.index),
3403
+ disabled: submitLoading2 || isSavingAsync2,
3404
+ 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",
3292
3405
  title: "Delete",
3293
- children: /* @__PURE__ */ jsx24(Trash2, { size: 16 })
3406
+ children: submitLoading2 || isSavingAsync2 ? /* @__PURE__ */ jsx24(Loader23, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Trash2, { size: 16 })
3294
3407
  }
3295
3408
  )
3296
3409
  ] });
3297
3410
  }
3298
- };
3411
+ }), []);
3299
3412
  const columns = useMemo4(() => {
3300
3413
  const mappedUserColumns = userColumns.map((col) => ({
3301
3414
  ...col,
@@ -3344,6 +3457,12 @@ function PostTable({
3344
3457
  columnFilters,
3345
3458
  columnVisibility,
3346
3459
  expanded
3460
+ },
3461
+ meta: {
3462
+ handleEdit,
3463
+ handleDelete,
3464
+ submitLoading,
3465
+ isSavingAsync
3347
3466
  }
3348
3467
  });
3349
3468
  return /* @__PURE__ */ jsx24(
@@ -3398,54 +3517,18 @@ function PostTable({
3398
3517
  ))
3399
3518
  },
3400
3519
  `skeleton-${i}`
3401
- )) : table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsxs18(React9.Fragment, { children: [
3402
- /* @__PURE__ */ jsx24(
3403
- "tr",
3404
- {
3405
- 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" : ""}`,
3406
- "data-state": row.getIsSelected() && "selected",
3407
- onClick: (e) => {
3408
- if (renderSubComponent && hasSubComponent(row.original)) {
3409
- const target = e.target;
3410
- if (!target.closest(
3411
- "button, a, input, select, textarea"
3412
- )) {
3413
- row.toggleExpanded();
3414
- }
3415
- }
3416
- },
3417
- children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx24(
3418
- "td",
3419
- {
3420
- className: cn(
3421
- rowPadding,
3422
- "text-sm text-gray-700 dark:text-gray-200",
3423
- verticalLines && "border-x border-gray-200 dark:border-zinc-800",
3424
- cell.column.id === "_index" && "w-[1%] min-w-[40px] max-w-[40px] whitespace-nowrap",
3425
- cell.column.columnDef.meta?.className
3426
- ),
3427
- style: {
3428
- width: cell.column.columnDef.meta?.width ?? cell.column.getSize(),
3429
- minWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.minSize,
3430
- maxWidth: cell.column.columnDef.meta?.width ?? cell.column.columnDef.maxSize
3431
- },
3432
- children: flexRender2(
3433
- cell.column.columnDef.cell,
3434
- cell.getContext()
3435
- )
3436
- },
3437
- cell.id
3438
- ))
3439
- }
3440
- ),
3441
- renderSubComponent && row.getIsExpanded() && hasSubComponent(row.original) && /* @__PURE__ */ jsx24("tr", { className: "border-b border-gray-200 dark:border-zinc-800 bg-gray-50/20 dark:bg-zinc-900/20", children: /* @__PURE__ */ jsx24("td", { colSpan: columns.length, className: "px-2 py-0", children: /* @__PURE__ */ jsxs18("div", { className: "relative pl-6 pb-2 pr-2 pt-2 h-full", children: [
3442
- /* @__PURE__ */ jsx24("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" }),
3443
- renderSubComponent({
3444
- row: row.original,
3445
- index: row.index
3446
- })
3447
- ] }) }) })
3448
- ] }, row.id)) : /* @__PURE__ */ jsx24("tr", { children: /* @__PURE__ */ jsx24(
3520
+ )) : table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx24(
3521
+ TableRow,
3522
+ {
3523
+ row,
3524
+ rowPadding,
3525
+ verticalLines,
3526
+ renderSubComponent,
3527
+ hasSubComponent,
3528
+ columnsCount: columns.length
3529
+ },
3530
+ row.id
3531
+ )) : /* @__PURE__ */ jsx24("tr", { children: /* @__PURE__ */ jsx24(
3449
3532
  "td",
3450
3533
  {
3451
3534
  colSpan: columns.length,
@@ -3481,17 +3564,17 @@ function PostTable({
3481
3564
  "button",
3482
3565
  {
3483
3566
  onClick: handleSaveField,
3484
- disabled: isSavingAsync,
3567
+ disabled: isSavingAsync || submitLoading,
3485
3568
  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",
3486
3569
  title: "Update",
3487
- children: isSavingAsync ? /* @__PURE__ */ jsx24("div", { className: "w-3.5 h-3.5 rounded-full border-2 border-emerald-500/30 border-t-emerald-500 animate-spin" }) : /* @__PURE__ */ jsx24(Check4, { size: 16, strokeWidth: 2.5 })
3570
+ children: isSavingAsync || submitLoading ? /* @__PURE__ */ jsx24(Loader23, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Check4, { size: 16, strokeWidth: 2.5 })
3488
3571
  }
3489
3572
  ),
3490
3573
  /* @__PURE__ */ jsx24(
3491
3574
  "button",
3492
3575
  {
3493
3576
  onClick: handleCancelEdit,
3494
- disabled: isSavingAsync,
3577
+ disabled: isSavingAsync || submitLoading,
3495
3578
  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",
3496
3579
  title: "Cancel",
3497
3580
  children: /* @__PURE__ */ jsx24(X3, { size: 16, strokeWidth: 2.5 })
@@ -3505,15 +3588,15 @@ function PostTable({
3505
3588
  "button",
3506
3589
  {
3507
3590
  onClick: handleSaveField,
3508
- disabled: isSavingAsync,
3591
+ disabled: isSavingAsync || submitLoading,
3509
3592
  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",
3510
3593
  style: {
3511
3594
  backgroundColor: "var(--theme-primary)"
3512
3595
  },
3513
3596
  title: "Add Row",
3514
3597
  children: [
3515
- isSavingAsync ? /* @__PURE__ */ jsx24("div", { className: "w-3.5 h-3.5 rounded-full border-2 border-white/30 border-t-white animate-spin" }) : /* @__PURE__ */ jsx24(Plus, { size: 14, strokeWidth: 2.5 }),
3516
- /* @__PURE__ */ jsx24("span", { children: isSavingAsync ? "Adding..." : "Add" })
3598
+ isSavingAsync || submitLoading ? /* @__PURE__ */ jsx24(Loader23, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Plus, { size: 14, strokeWidth: 2.5 }),
3599
+ /* @__PURE__ */ jsx24("span", { children: isSavingAsync || submitLoading ? "Adding..." : "Add" })
3517
3600
  ]
3518
3601
  }
3519
3602
  ) }) })
@@ -3670,7 +3753,8 @@ function SimpleTable({
3670
3753
  startIndex = 0,
3671
3754
  isLoading = false,
3672
3755
  title,
3673
- enableSearch = false
3756
+ enableSearch = false,
3757
+ emptyState
3674
3758
  }) {
3675
3759
  const columns = useMemo5(() => {
3676
3760
  const cols = userColumns.filter((col) => !col.hide).map((col) => ({
@@ -3752,8 +3836,8 @@ function SimpleTable({
3752
3836
  "td",
3753
3837
  {
3754
3838
  colSpan: columns.length,
3755
- className: "text-center py-8 text-gray-500 font-medium",
3756
- children: "No transactions found."
3839
+ className: "text-center text-gray-500 font-medium",
3840
+ children: emptyState || /* @__PURE__ */ jsx25("div", { className: "py-8", children: "No transactions found." })
3757
3841
  }
3758
3842
  ) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx25(
3759
3843
  "tr",
@@ -4026,24 +4110,22 @@ var useA4StatementView = ({
4026
4110
  }
4027
4111
  );
4028
4112
  const DisplayInfoGridEl = Array.isArray(info) && info.length > 0 ? /* @__PURE__ */ jsx28("div", { id: "a4-info-grid", className: "px-8", children: /* @__PURE__ */ jsx28(InfoGrid, { className: "mb-4", items: info, isLoading }) }) : null;
4029
- if (!isLoading && (error || !data || data.length === 0)) {
4030
- return /* @__PURE__ */ jsx28("div", { className: "flex flex-col relative w-full items-center justify-center p-8 min-h-96", children: /* @__PURE__ */ jsxs20("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: [
4031
- error ? /* @__PURE__ */ jsx28("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__ */ jsx28(AlertCircle, { className: "w-8 h-8 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ jsx28("div", { className: "w-16 h-16 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-6", children: /* @__PURE__ */ jsx28(FileX, { className: "w-8 h-8 text-gray-500 dark:text-gray-400" }) }),
4032
- /* @__PURE__ */ jsx28("h3", { className: "text-xl font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Statement" : "No Records Found" }),
4033
- /* @__PURE__ */ jsx28("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." }),
4034
- url && /* @__PURE__ */ jsxs20(
4035
- "button",
4036
- {
4037
- onClick: () => get({ url, v, params, delay }),
4038
- 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",
4039
- children: [
4040
- /* @__PURE__ */ jsx28(RefreshCw, { size: 16 }),
4041
- "Try Again"
4042
- ]
4043
- }
4044
- )
4045
- ] }) });
4046
- }
4113
+ const emptyState = !isLoading && (error || !data || data.length === 0) ? /* @__PURE__ */ jsx28("div", { className: "flex flex-col relative w-full items-center justify-center py-12 min-h-[300px]", children: /* @__PURE__ */ jsxs20("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: [
4114
+ error ? /* @__PURE__ */ jsx28("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__ */ jsx28(AlertCircle, { className: "w-7 h-7 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ jsx28("div", { className: "w-14 h-14 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx28(FileX, { className: "w-7 h-7 text-gray-500 dark:text-gray-400" }) }),
4115
+ /* @__PURE__ */ jsx28("h3", { className: "text-lg font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Statement" : "No Records Found" }),
4116
+ /* @__PURE__ */ jsx28("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." }),
4117
+ url && /* @__PURE__ */ jsxs20(
4118
+ "button",
4119
+ {
4120
+ onClick: () => get({ url, v, params, delay }),
4121
+ 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",
4122
+ children: [
4123
+ /* @__PURE__ */ jsx28(RefreshCw, { size: 14 }),
4124
+ "Try Again"
4125
+ ]
4126
+ }
4127
+ )
4128
+ ] }) }) : void 0;
4047
4129
  return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col relative w-full items-center", children: [
4048
4130
  isMeasuring && filteredDisplayData.length > 0 && /* @__PURE__ */ jsx28("div", { className: "absolute top-0 opacity-0 pointer-events-none -left-full", children: /* @__PURE__ */ jsx28(
4049
4131
  "div",
@@ -4138,7 +4220,7 @@ var useA4StatementView = ({
4138
4220
  ] }),
4139
4221
  pageIndex === 0 && /* @__PURE__ */ jsx28("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__ */ jsx28("h3", { className: "text-sm font-bold text-gray-800 print:text-gray-800 uppercase tracking-wide shrink-0", children: "Recent Transactions" }) }),
4140
4222
  pageIndex > 0 && /* @__PURE__ */ jsx28("div", { className: "h-5 print:h-0" }),
4141
- (pageData.length > 0 || isLoading) && /* @__PURE__ */ jsx28(
4223
+ /* @__PURE__ */ jsx28(
4142
4224
  SimpleTable,
4143
4225
  {
4144
4226
  columns,
@@ -4148,6 +4230,7 @@ var useA4StatementView = ({
4148
4230
  index,
4149
4231
  startIndex: pages.slice(0, pageIndex).reduce((acc, curr) => acc + curr.length, 0),
4150
4232
  verticalLines,
4233
+ emptyState,
4151
4234
  isLoading: isLoading || isMeasuring && pages.length === 1 && pages[0].length === 0
4152
4235
  }
4153
4236
  ),
@@ -4229,30 +4312,28 @@ var useTransaction = ({
4229
4312
  createTitle = "Add New",
4230
4313
  ...rest
4231
4314
  }) => {
4232
- if (!isLoading && (error || !data || data.length === 0)) {
4233
- return /* @__PURE__ */ jsx29(
4234
- "div",
4235
- {
4236
- className: `flex flex-col relative w-full items-center justify-center p-8 min-h-96 ${className}`,
4237
- children: /* @__PURE__ */ jsxs21("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: [
4238
- error ? /* @__PURE__ */ jsx29("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__ */ jsx29(AlertCircle2, { className: "w-8 h-8 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ jsx29("div", { className: "w-16 h-16 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-6", children: /* @__PURE__ */ jsx29(FileX2, { className: "w-8 h-8 text-gray-500 dark:text-gray-400" }) }),
4239
- /* @__PURE__ */ jsx29("h3", { className: "text-xl font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Data" : "No Records Found" }),
4240
- /* @__PURE__ */ jsx29("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." }),
4241
- url && /* @__PURE__ */ jsxs21(
4242
- "button",
4243
- {
4244
- onClick: () => get({ url, v, params, delay }),
4245
- 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",
4246
- children: [
4247
- /* @__PURE__ */ jsx29(RefreshCw2, { size: 16 }),
4248
- "Try Again"
4249
- ]
4250
- }
4251
- )
4252
- ] })
4253
- }
4254
- );
4255
- }
4315
+ const emptyState = !isLoading && (error || !data || data.length === 0) ? /* @__PURE__ */ jsx29(
4316
+ "div",
4317
+ {
4318
+ className: `flex flex-col relative w-full items-center justify-center py-12 min-h-[300px] ${className}`,
4319
+ children: /* @__PURE__ */ jsxs21("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: [
4320
+ error ? /* @__PURE__ */ jsx29("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__ */ jsx29(AlertCircle2, { className: "w-7 h-7 text-red-600 dark:text-red-500" }) }) : /* @__PURE__ */ jsx29("div", { className: "w-14 h-14 bg-gray-200 dark:bg-zinc-800 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx29(FileX2, { className: "w-7 h-7 text-gray-500 dark:text-gray-400" }) }),
4321
+ /* @__PURE__ */ jsx29("h3", { className: "text-lg font-bold text-gray-900 dark:text-white mb-2", children: error ? "Failed to Load Data" : "No Records Found" }),
4322
+ /* @__PURE__ */ jsx29("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." }),
4323
+ url && /* @__PURE__ */ jsxs21(
4324
+ "button",
4325
+ {
4326
+ onClick: () => get({ url, v, params, delay }),
4327
+ 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",
4328
+ children: [
4329
+ /* @__PURE__ */ jsx29(RefreshCw2, { size: 14 }),
4330
+ "Try Again"
4331
+ ]
4332
+ }
4333
+ )
4334
+ ] })
4335
+ }
4336
+ ) : void 0;
4256
4337
  return /* @__PURE__ */ jsxs21(Card, { children: [
4257
4338
  /* @__PURE__ */ jsx29(Card.Header, { children: /* @__PURE__ */ jsxs21("header", { className: "flex items-center justify-between gap-4 py-2", children: [
4258
4339
  /* @__PURE__ */ jsxs21("div", { className: "space-y-1", children: [
@@ -4296,6 +4377,7 @@ var useTransaction = ({
4296
4377
  verticalLines,
4297
4378
  index,
4298
4379
  rowPadding,
4380
+ emptyState,
4299
4381
  ...rest
4300
4382
  }
4301
4383
  ) }) })
@@ -4437,6 +4519,66 @@ var generatePdf = async (elementId, options = {}) => {
4437
4519
  throw error;
4438
4520
  }
4439
4521
  };
4522
+
4523
+ // src/utils/storage.ts
4524
+ var isBrowser = typeof window !== "undefined" && typeof localStorage !== "undefined";
4525
+ var storage = {
4526
+ set(key, value) {
4527
+ if (!isBrowser) return;
4528
+ try {
4529
+ localStorage.setItem(key, JSON.stringify(value));
4530
+ } catch (error) {
4531
+ console.error(`[storage] Error saving key "${key}":`, error);
4532
+ }
4533
+ },
4534
+ get(key) {
4535
+ if (!isBrowser) return key ? null : {};
4536
+ if (key !== void 0) {
4537
+ try {
4538
+ const item = localStorage.getItem(key);
4539
+ if (item === null) return null;
4540
+ return JSON.parse(item);
4541
+ } catch (error) {
4542
+ const rawValue = localStorage.getItem(key);
4543
+ return rawValue;
4544
+ }
4545
+ }
4546
+ const allItems = {};
4547
+ for (let i = 0; i < localStorage.length; i++) {
4548
+ const k = localStorage.key(i);
4549
+ if (k) {
4550
+ const value = localStorage.getItem(k);
4551
+ try {
4552
+ allItems[k] = value ? JSON.parse(value) : null;
4553
+ } catch {
4554
+ allItems[k] = value;
4555
+ }
4556
+ }
4557
+ }
4558
+ return allItems;
4559
+ },
4560
+ remove(key) {
4561
+ if (!isBrowser) return;
4562
+ localStorage.removeItem(key);
4563
+ },
4564
+ clear() {
4565
+ if (!isBrowser) return;
4566
+ localStorage.clear();
4567
+ },
4568
+ has(key) {
4569
+ if (!isBrowser) return false;
4570
+ return localStorage.getItem(key) !== null;
4571
+ },
4572
+ keys() {
4573
+ if (!isBrowser) return [];
4574
+ const keys = [];
4575
+ for (let i = 0; i < localStorage.length; i++) {
4576
+ const key = localStorage.key(i);
4577
+ if (key) keys.push(key);
4578
+ }
4579
+ return keys;
4580
+ }
4581
+ };
4440
4582
  export {
4441
4583
  A4DataView,
4442
4584
  Badge,
@@ -4479,6 +4621,7 @@ export {
4479
4621
  ThemeToggle,
4480
4622
  WarqadProvider,
4481
4623
  generatePdf,
4624
+ storage,
4482
4625
  useA4DataView_default as useA4StatementView,
4483
4626
  useApis_default as useApi,
4484
4627
  useModal,