@northslopetech/altitude-ui 2.6.3 → 2.7.0

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
@@ -1916,6 +1916,124 @@ var Panel = ({
1916
1916
  )
1917
1917
  }
1918
1918
  );
1919
+ var ZoomIn = ({
1920
+ className,
1921
+ variant = "dark",
1922
+ ...props
1923
+ }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1924
+ "svg",
1925
+ {
1926
+ width: "16",
1927
+ height: "16",
1928
+ viewBox: "0 0 16 16",
1929
+ fill: "none",
1930
+ xmlns: "http://www.w3.org/2000/svg",
1931
+ className: cn(getVariantStyles(variant), className),
1932
+ ...props,
1933
+ children: [
1934
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1935
+ "circle",
1936
+ {
1937
+ cx: "6.5",
1938
+ cy: "6.5",
1939
+ r: "4.5",
1940
+ stroke: "currentColor",
1941
+ strokeWidth: "1.5",
1942
+ fill: "none"
1943
+ }
1944
+ ),
1945
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1946
+ "line",
1947
+ {
1948
+ x1: "10",
1949
+ y1: "10",
1950
+ x2: "14",
1951
+ y2: "14",
1952
+ stroke: "currentColor",
1953
+ strokeWidth: "1.5",
1954
+ strokeLinecap: "round"
1955
+ }
1956
+ ),
1957
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1958
+ "line",
1959
+ {
1960
+ x1: "4.5",
1961
+ y1: "6.5",
1962
+ x2: "8.5",
1963
+ y2: "6.5",
1964
+ stroke: "currentColor",
1965
+ strokeWidth: "1.5",
1966
+ strokeLinecap: "round"
1967
+ }
1968
+ ),
1969
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1970
+ "line",
1971
+ {
1972
+ x1: "6.5",
1973
+ y1: "4.5",
1974
+ x2: "6.5",
1975
+ y2: "8.5",
1976
+ stroke: "currentColor",
1977
+ strokeWidth: "1.5",
1978
+ strokeLinecap: "round"
1979
+ }
1980
+ )
1981
+ ]
1982
+ }
1983
+ );
1984
+ var ZoomOut = ({
1985
+ className,
1986
+ variant = "dark",
1987
+ ...props
1988
+ }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1989
+ "svg",
1990
+ {
1991
+ width: "16",
1992
+ height: "16",
1993
+ viewBox: "0 0 16 16",
1994
+ fill: "none",
1995
+ xmlns: "http://www.w3.org/2000/svg",
1996
+ className: cn(getVariantStyles(variant), className),
1997
+ ...props,
1998
+ children: [
1999
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2000
+ "circle",
2001
+ {
2002
+ cx: "6.5",
2003
+ cy: "6.5",
2004
+ r: "4.5",
2005
+ stroke: "currentColor",
2006
+ strokeWidth: "1.5",
2007
+ fill: "none"
2008
+ }
2009
+ ),
2010
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2011
+ "line",
2012
+ {
2013
+ x1: "10",
2014
+ y1: "10",
2015
+ x2: "14",
2016
+ y2: "14",
2017
+ stroke: "currentColor",
2018
+ strokeWidth: "1.5",
2019
+ strokeLinecap: "round"
2020
+ }
2021
+ ),
2022
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2023
+ "line",
2024
+ {
2025
+ x1: "4.5",
2026
+ y1: "6.5",
2027
+ x2: "8.5",
2028
+ y2: "6.5",
2029
+ stroke: "currentColor",
2030
+ strokeWidth: "1.5",
2031
+ strokeLinecap: "round"
2032
+ }
2033
+ )
2034
+ ]
2035
+ }
2036
+ );
1919
2037
 
1920
2038
  // src/components/ui/select.tsx
1921
2039
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -3410,103 +3528,588 @@ var Badge = React11.forwardRef(
3410
3528
  Badge.displayName = "Badge";
3411
3529
 
3412
3530
  // src/components/pdf-viewer/index.tsx
3413
- var React16 = __toESM(require("react"));
3531
+ var React19 = __toESM(require("react"));
3414
3532
  var import_TextLayer = require("react-pdf/dist/Page/TextLayer.css");
3415
3533
 
3416
- // src/components/pdf-viewer/components/PdfDocument.tsx
3534
+ // src/components/pdf-viewer/components/CustomScrollbar.tsx
3417
3535
  var React12 = __toESM(require("react"));
3418
- var import_react_pdf = require("react-pdf");
3419
3536
  var import_jsx_runtime16 = require("react/jsx-runtime");
3537
+ var scrollbarStyles = `
3538
+ .custom-scrollbar-content {
3539
+ overflow: auto;
3540
+ scrollbar-width: none;
3541
+ -ms-overflow-style: none;
3542
+ }
3543
+ .custom-scrollbar-content::-webkit-scrollbar {
3544
+ width: 0;
3545
+ height: 0;
3546
+ display: none;
3547
+ }
3548
+ .custom-scrollbar-wrapper {
3549
+ position: relative;
3550
+ }
3551
+ .custom-scrollbar-wrapper .scrollbar-track-vertical {
3552
+ position: absolute;
3553
+ top: 0;
3554
+ right: 0;
3555
+ width: 8px;
3556
+ height: 100%;
3557
+ pointer-events: none;
3558
+ z-index: 10;
3559
+ }
3560
+ .custom-scrollbar-wrapper .scrollbar-track-horizontal {
3561
+ position: absolute;
3562
+ bottom: 0;
3563
+ left: 0;
3564
+ width: 100%;
3565
+ height: 8px;
3566
+ pointer-events: none;
3567
+ z-index: 10;
3568
+ }
3569
+ .custom-scrollbar-wrapper .scrollbar-thumb-vertical {
3570
+ position: absolute;
3571
+ right: 0;
3572
+ width: 8px;
3573
+ border-radius: 4px;
3574
+ background: rgba(102, 102, 102, 0);
3575
+ transition: background 0.3s ease;
3576
+ pointer-events: auto;
3577
+ cursor: default;
3578
+ }
3579
+ .custom-scrollbar-wrapper .scrollbar-thumb-horizontal {
3580
+ position: absolute;
3581
+ bottom: 0;
3582
+ height: 8px;
3583
+ border-radius: 4px;
3584
+ background: rgba(102, 102, 102, 0);
3585
+ transition: background 0.3s ease;
3586
+ pointer-events: auto;
3587
+ cursor: default;
3588
+ }
3589
+ .custom-scrollbar-wrapper.scrolling-vertical .scrollbar-thumb-vertical {
3590
+ background: rgba(102, 102, 102, 0.7);
3591
+ }
3592
+ .custom-scrollbar-wrapper.scrolling-horizontal .scrollbar-thumb-horizontal {
3593
+ background: rgba(102, 102, 102, 0.7);
3594
+ }
3595
+ `;
3596
+ function CustomScrollbar({
3597
+ children,
3598
+ containerRef: externalContainerRef,
3599
+ autoHideDelay = 1e3,
3600
+ onScroll,
3601
+ backgroundColor = "#F5F5F5",
3602
+ className
3603
+ }) {
3604
+ const internalContainerRef = React12.useRef(null);
3605
+ const containerRef = externalContainerRef || internalContainerRef;
3606
+ const wrapperRef = React12.useRef(null);
3607
+ const thumbVerticalRef = React12.useRef(null);
3608
+ const thumbHorizontalRef = React12.useRef(null);
3609
+ const lastScrollPosRef = React12.useRef({ top: 0, left: 0 });
3610
+ const scrollTimeoutsRef = React12.useRef({ vertical: null, horizontal: null });
3611
+ const showScrollbar = React12.useCallback(
3612
+ (direction) => {
3613
+ const wrapper = wrapperRef.current;
3614
+ if (!wrapper) return;
3615
+ wrapper.classList.add(`scrolling-${direction}`);
3616
+ if (scrollTimeoutsRef.current[direction]) {
3617
+ clearTimeout(scrollTimeoutsRef.current[direction]);
3618
+ }
3619
+ scrollTimeoutsRef.current[direction] = setTimeout(() => {
3620
+ wrapper.classList.remove(`scrolling-${direction}`);
3621
+ }, autoHideDelay);
3622
+ },
3623
+ [autoHideDelay]
3624
+ );
3625
+ const updateScrollbarThumbPosition = React12.useCallback(() => {
3626
+ const container = containerRef.current;
3627
+ const thumbVertical = thumbVerticalRef.current;
3628
+ const thumbHorizontal = thumbHorizontalRef.current;
3629
+ if (!container) return;
3630
+ if (thumbVertical) {
3631
+ const { scrollTop, scrollHeight, clientHeight } = container;
3632
+ const scrollableHeight = scrollHeight - clientHeight;
3633
+ if (scrollableHeight <= 0) {
3634
+ thumbVertical.style.display = "none";
3635
+ } else {
3636
+ thumbVertical.style.display = "block";
3637
+ const thumbHeight = Math.max(
3638
+ clientHeight / scrollHeight * clientHeight,
3639
+ 30
3640
+ );
3641
+ const thumbTop = scrollTop / scrollableHeight * (clientHeight - thumbHeight);
3642
+ thumbVertical.style.height = `${thumbHeight}px`;
3643
+ thumbVertical.style.top = `${thumbTop}px`;
3644
+ }
3645
+ }
3646
+ if (thumbHorizontal) {
3647
+ const { scrollLeft, scrollWidth, clientWidth } = container;
3648
+ const scrollableWidth = scrollWidth - clientWidth;
3649
+ if (scrollableWidth <= 0) {
3650
+ thumbHorizontal.style.display = "none";
3651
+ } else {
3652
+ thumbHorizontal.style.display = "block";
3653
+ const thumbWidth = Math.max(
3654
+ clientWidth / scrollWidth * clientWidth,
3655
+ 30
3656
+ );
3657
+ const thumbLeft = scrollLeft / scrollableWidth * (clientWidth - thumbWidth);
3658
+ thumbHorizontal.style.width = `${thumbWidth}px`;
3659
+ thumbHorizontal.style.left = `${thumbLeft}px`;
3660
+ }
3661
+ }
3662
+ }, [containerRef]);
3663
+ React12.useEffect(() => {
3664
+ const container = containerRef.current;
3665
+ if (!container) return;
3666
+ lastScrollPosRef.current = {
3667
+ top: container.scrollTop,
3668
+ left: container.scrollLeft
3669
+ };
3670
+ let rafId = null;
3671
+ const handleScroll = () => {
3672
+ const currentScrollTop = container.scrollTop;
3673
+ const currentScrollLeft = container.scrollLeft;
3674
+ if (currentScrollTop !== lastScrollPosRef.current.top) {
3675
+ showScrollbar("vertical");
3676
+ }
3677
+ if (currentScrollLeft !== lastScrollPosRef.current.left) {
3678
+ showScrollbar("horizontal");
3679
+ }
3680
+ lastScrollPosRef.current = {
3681
+ top: currentScrollTop,
3682
+ left: currentScrollLeft
3683
+ };
3684
+ if (rafId) return;
3685
+ rafId = requestAnimationFrame(() => {
3686
+ updateScrollbarThumbPosition();
3687
+ rafId = null;
3688
+ });
3689
+ };
3690
+ container.addEventListener("scroll", handleScroll, { passive: true });
3691
+ return () => {
3692
+ container.removeEventListener("scroll", handleScroll);
3693
+ if (rafId) cancelAnimationFrame(rafId);
3694
+ };
3695
+ }, [containerRef, showScrollbar, updateScrollbarThumbPosition]);
3696
+ React12.useEffect(() => {
3697
+ const thumbVertical = thumbVerticalRef.current;
3698
+ const thumbHorizontal = thumbHorizontalRef.current;
3699
+ const container = containerRef.current;
3700
+ if (!container) return;
3701
+ let activeDrag = null;
3702
+ let startPos = 0;
3703
+ let startScroll = 0;
3704
+ const handleMouseDown = (direction) => {
3705
+ return (e) => {
3706
+ activeDrag = direction;
3707
+ startPos = direction === "vertical" ? e.clientY : e.clientX;
3708
+ startScroll = direction === "vertical" ? container.scrollTop : container.scrollLeft;
3709
+ showScrollbar(direction);
3710
+ document.body.style.userSelect = "none";
3711
+ e.preventDefault();
3712
+ };
3713
+ };
3714
+ const handleMouseMove = (e) => {
3715
+ if (!activeDrag) return;
3716
+ if (activeDrag === "vertical") {
3717
+ const { scrollHeight, clientHeight } = container;
3718
+ const scrollableHeight = scrollHeight - clientHeight;
3719
+ const thumbHeight = Math.max(
3720
+ clientHeight / scrollHeight * clientHeight,
3721
+ 30
3722
+ );
3723
+ const trackHeight = clientHeight - thumbHeight;
3724
+ const delta = e.clientY - startPos;
3725
+ container.scrollTop = startScroll + delta / trackHeight * scrollableHeight;
3726
+ } else {
3727
+ const { scrollWidth, clientWidth } = container;
3728
+ const scrollableWidth = scrollWidth - clientWidth;
3729
+ const thumbWidth = Math.max(
3730
+ clientWidth / scrollWidth * clientWidth,
3731
+ 30
3732
+ );
3733
+ const trackWidth = clientWidth - thumbWidth;
3734
+ const delta = e.clientX - startPos;
3735
+ container.scrollLeft = startScroll + delta / trackWidth * scrollableWidth;
3736
+ }
3737
+ };
3738
+ const handleMouseUp = () => {
3739
+ if (!activeDrag) return;
3740
+ activeDrag = null;
3741
+ document.body.style.userSelect = "";
3742
+ };
3743
+ const onVerticalMouseDown = handleMouseDown("vertical");
3744
+ const onHorizontalMouseDown = handleMouseDown("horizontal");
3745
+ thumbVertical?.addEventListener("mousedown", onVerticalMouseDown);
3746
+ thumbHorizontal?.addEventListener("mousedown", onHorizontalMouseDown);
3747
+ document.addEventListener("mousemove", handleMouseMove);
3748
+ document.addEventListener("mouseup", handleMouseUp);
3749
+ return () => {
3750
+ thumbVertical?.removeEventListener("mousedown", onVerticalMouseDown);
3751
+ thumbHorizontal?.removeEventListener("mousedown", onHorizontalMouseDown);
3752
+ document.removeEventListener("mousemove", handleMouseMove);
3753
+ document.removeEventListener("mouseup", handleMouseUp);
3754
+ };
3755
+ }, [containerRef, showScrollbar]);
3756
+ React12.useEffect(() => {
3757
+ updateScrollbarThumbPosition();
3758
+ }, [children, updateScrollbarThumbPosition]);
3759
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3760
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("style", { children: scrollbarStyles }),
3761
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3762
+ "div",
3763
+ {
3764
+ ref: wrapperRef,
3765
+ className: `flex-1 min-w-0 custom-scrollbar-wrapper ${className || ""}`,
3766
+ style: { background: backgroundColor },
3767
+ children: [
3768
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3769
+ "div",
3770
+ {
3771
+ ref: containerRef,
3772
+ className: "h-full custom-scrollbar-content",
3773
+ onScroll,
3774
+ children
3775
+ }
3776
+ ),
3777
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "scrollbar-track-vertical", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: thumbVerticalRef, className: "scrollbar-thumb-vertical" }) }),
3778
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "scrollbar-track-horizontal", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3779
+ "div",
3780
+ {
3781
+ ref: thumbHorizontalRef,
3782
+ className: "scrollbar-thumb-horizontal"
3783
+ }
3784
+ ) })
3785
+ ]
3786
+ }
3787
+ )
3788
+ ] });
3789
+ }
3790
+
3791
+ // src/components/pdf-viewer/components/PdfControls.tsx
3792
+ var React13 = __toESM(require("react"));
3793
+
3794
+ // src/components/pdf-viewer/utils/types.ts
3795
+ var PDF_ZOOM = {
3796
+ MIN: 25,
3797
+ MAX: 300,
3798
+ DEFAULT: 100,
3799
+ STEP: 25
3800
+ };
3801
+
3802
+ // src/components/pdf-viewer/components/PdfControls.tsx
3803
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3804
+ var PdfControls = ({
3805
+ currentPage,
3806
+ totalPages,
3807
+ onPageChange,
3808
+ onPreviousPage,
3809
+ onNextPage,
3810
+ zoom,
3811
+ onZoomChange
3812
+ }) => {
3813
+ const canGoPrevious = currentPage > 1;
3814
+ const canGoNext = currentPage < totalPages;
3815
+ const canZoomIn = zoom < PDF_ZOOM.MAX;
3816
+ const canZoomOut = zoom > PDF_ZOOM.MIN;
3817
+ const [pageInputValue, setPageInputValue] = React13.useState(
3818
+ String(currentPage)
3819
+ );
3820
+ const isEscapeRef = React13.useRef(false);
3821
+ React13.useEffect(() => {
3822
+ setPageInputValue(String(currentPage));
3823
+ }, [currentPage]);
3824
+ const handlePageInputChange = (e) => {
3825
+ setPageInputValue(e.target.value);
3826
+ };
3827
+ const handlePageInputBlur = () => {
3828
+ if (isEscapeRef.current) {
3829
+ isEscapeRef.current = false;
3830
+ return;
3831
+ }
3832
+ const pageNum = parseInt(pageInputValue, 10);
3833
+ if (!isNaN(pageNum) && pageNum >= 1 && pageNum <= totalPages) {
3834
+ onPageChange?.(pageNum);
3835
+ } else {
3836
+ setPageInputValue(String(currentPage));
3837
+ }
3838
+ };
3839
+ const handlePageKeyDown = (e) => {
3840
+ if (e.key === "Enter") {
3841
+ handlePageInputBlur();
3842
+ e.target.blur();
3843
+ } else if (e.key === "Escape") {
3844
+ isEscapeRef.current = true;
3845
+ setPageInputValue(String(currentPage));
3846
+ e.target.blur();
3847
+ }
3848
+ };
3849
+ const handleZoomIn = () => {
3850
+ const newZoom = Math.min(zoom + PDF_ZOOM.STEP, PDF_ZOOM.MAX);
3851
+ onZoomChange(newZoom);
3852
+ };
3853
+ const handleZoomOut = () => {
3854
+ const newZoom = Math.max(zoom - PDF_ZOOM.STEP, PDF_ZOOM.MIN);
3855
+ onZoomChange(newZoom);
3856
+ };
3857
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3858
+ "div",
3859
+ {
3860
+ className: "flex flex-col items-center justify-end py-2 px-1 gap-4",
3861
+ style: { background: "#DEDEDE" },
3862
+ children: [
3863
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
3864
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3865
+ "button",
3866
+ {
3867
+ onClick: onPreviousPage,
3868
+ disabled: !canGoPrevious,
3869
+ className: "p-1.5 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
3870
+ "aria-label": "Previous page",
3871
+ type: "button",
3872
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronUp, { className: "w-4 h-4", style: { color: "#666666" } })
3873
+ }
3874
+ ),
3875
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex flex-col items-center", children: totalPages > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3876
+ "input",
3877
+ {
3878
+ type: "text",
3879
+ inputMode: "numeric",
3880
+ value: pageInputValue,
3881
+ onChange: handlePageInputChange,
3882
+ onBlur: handlePageInputBlur,
3883
+ onKeyDown: handlePageKeyDown,
3884
+ className: "w-8 px-1 py-0.5 text-center text-sm rounded focus:outline-none focus:ring-1 focus:ring-primary",
3885
+ style: {
3886
+ background: "white",
3887
+ border: "1px solid #CCCCCC"
3888
+ },
3889
+ "aria-label": "Current page"
3890
+ }
3891
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-sm", style: { color: "#666666" }, children: "-" }) }),
3892
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3893
+ "button",
3894
+ {
3895
+ onClick: onNextPage,
3896
+ disabled: !canGoNext,
3897
+ className: "p-1.5 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
3898
+ "aria-label": "Next page",
3899
+ type: "button",
3900
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDown, { className: "w-4 h-4", style: { color: "#666666" } })
3901
+ }
3902
+ )
3903
+ ] }),
3904
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
3905
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3906
+ "button",
3907
+ {
3908
+ onClick: handleZoomIn,
3909
+ disabled: !canZoomIn,
3910
+ className: "p-1.5 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
3911
+ "aria-label": "Zoom in",
3912
+ type: "button",
3913
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ZoomIn, { className: "w-4 h-4", style: { color: "#666666" } })
3914
+ }
3915
+ ),
3916
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3917
+ "button",
3918
+ {
3919
+ onClick: handleZoomOut,
3920
+ disabled: !canZoomOut,
3921
+ className: "p-1.5 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
3922
+ "aria-label": "Zoom out",
3923
+ type: "button",
3924
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ZoomOut, { className: "w-4 h-4", style: { color: "#666666" } })
3925
+ }
3926
+ )
3927
+ ] })
3928
+ ]
3929
+ }
3930
+ );
3931
+ };
3932
+ PdfControls.displayName = "PdfControls";
3933
+
3934
+ // src/components/pdf-viewer/components/PdfDocument.tsx
3935
+ var import_react_pdf = require("react-pdf");
3936
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3937
+ var DEFAULT_ASPECT_RATIO = 11 / 8.5;
3420
3938
  var PdfDocument = ({
3421
3939
  file,
3422
3940
  pageWidth,
3423
3941
  enableTextLayer,
3424
3942
  onLoadSuccess,
3425
- onLoadError
3943
+ onLoadError,
3944
+ numPages,
3945
+ registerPageRef,
3946
+ visiblePages,
3947
+ viewMode,
3948
+ currentPage
3426
3949
  }) => {
3427
- const [numPages, setNumPages] = React12.useState();
3950
+ const placeholderHeight = pageWidth * DEFAULT_ASPECT_RATIO;
3428
3951
  function handleDocumentLoadSuccess({ numPages: numPages2 }) {
3429
- setNumPages(numPages2);
3430
3952
  onLoadSuccess?.(numPages2);
3431
3953
  }
3954
+ function renderCurrentPage() {
3955
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3956
+ "div",
3957
+ {
3958
+ ref: (el) => registerPageRef(currentPage, el),
3959
+ className: "flex justify-center",
3960
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3961
+ import_react_pdf.Page,
3962
+ {
3963
+ pageNumber: currentPage,
3964
+ width: pageWidth,
3965
+ className: "shadow-sm",
3966
+ renderTextLayer: enableTextLayer,
3967
+ renderAnnotationLayer: false,
3968
+ loading: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3969
+ "div",
3970
+ {
3971
+ className: "flex items-center justify-center bg-white",
3972
+ style: { width: pageWidth, height: placeholderHeight },
3973
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Typography, { variant: "body-sm", className: "text-secondary", children: [
3974
+ "Loading page ",
3975
+ currentPage,
3976
+ "..."
3977
+ ] })
3978
+ }
3979
+ )
3980
+ }
3981
+ )
3982
+ },
3983
+ `page_${currentPage}`
3984
+ );
3985
+ }
3986
+ function renderPagesWithVirtualization() {
3987
+ return Array.from(new Array(numPages), (_, index) => {
3988
+ const pageNum = index + 1;
3989
+ const shouldRender = visiblePages.has(pageNum);
3990
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3991
+ "div",
3992
+ {
3993
+ ref: (el) => registerPageRef(pageNum, el),
3994
+ className: "mb-4 flex justify-center",
3995
+ style: {
3996
+ minHeight: shouldRender ? void 0 : placeholderHeight
3997
+ },
3998
+ children: shouldRender ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3999
+ import_react_pdf.Page,
4000
+ {
4001
+ pageNumber: pageNum,
4002
+ width: pageWidth,
4003
+ className: "shadow-sm",
4004
+ renderTextLayer: enableTextLayer,
4005
+ renderAnnotationLayer: false,
4006
+ loading: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4007
+ "div",
4008
+ {
4009
+ className: "flex items-center justify-center bg-white",
4010
+ style: { width: pageWidth, height: placeholderHeight },
4011
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Typography, { variant: "body-sm", className: "text-secondary", children: [
4012
+ "Loading page ",
4013
+ pageNum,
4014
+ "..."
4015
+ ] })
4016
+ }
4017
+ )
4018
+ }
4019
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4020
+ "div",
4021
+ {
4022
+ className: "flex items-center justify-center bg-white shadow-sm",
4023
+ style: {
4024
+ width: pageWidth,
4025
+ height: placeholderHeight
4026
+ },
4027
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Typography, { variant: "body-sm", className: "text-secondary", children: [
4028
+ "Page ",
4029
+ pageNum
4030
+ ] })
4031
+ }
4032
+ )
4033
+ },
4034
+ `page_${pageNum}`
4035
+ );
4036
+ });
4037
+ }
3432
4038
  if (!file) {
3433
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No PDF available" }) });
4039
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No PDF available" }) });
3434
4040
  }
3435
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4041
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3436
4042
  import_react_pdf.Document,
3437
4043
  {
3438
4044
  file,
3439
4045
  onLoadSuccess: handleDocumentLoadSuccess,
3440
4046
  onLoadError,
3441
- loading: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "Rendering PDF..." }) }),
3442
- error: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Typography, { variant: "body-md", className: "text-error", children: "Failed to render PDF" }) }),
3443
- className: "flex flex-col items-center p-4",
3444
- children: numPages && pageWidth > 0 && Array.from(new Array(numPages), (_, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3445
- import_react_pdf.Page,
3446
- {
3447
- pageNumber: index + 1,
3448
- width: pageWidth,
3449
- className: "mb-4 shadow-sm",
3450
- renderTextLayer: enableTextLayer,
3451
- renderAnnotationLayer: false
3452
- },
3453
- `page_${index + 1}`
3454
- ))
4047
+ loading: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "Rendering PDF..." }) }),
4048
+ error: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Typography, { variant: "body-md", className: "text-error", children: "Failed to render PDF" }) }),
4049
+ className: "flex flex-col items-center p-4 min-w-fit",
4050
+ children: numPages > 0 && pageWidth > 0 && (viewMode === "single" ? renderCurrentPage() : renderPagesWithVirtualization())
3455
4051
  }
3456
4052
  );
3457
4053
  };
3458
4054
  PdfDocument.displayName = "PdfDocument";
3459
4055
 
3460
4056
  // src/components/pdf-viewer/components/PdfHeader.tsx
3461
- var import_jsx_runtime17 = require("react/jsx-runtime");
4057
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3462
4058
  var PdfHeader = ({
3463
4059
  title,
3464
4060
  onDownload,
3465
4061
  onPrint
3466
4062
  }) => {
3467
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between gap-4 px-4 py-3 bg-neutral-400 border-b border-subtle", children: [
3468
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-shrink min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3469
- Typography,
3470
- {
3471
- variant: "label-md-bold",
3472
- className: "text-dark truncate",
3473
- title,
3474
- children: title || "Untitled Document"
3475
- }
3476
- ) }),
3477
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
3478
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3479
- "button",
3480
- {
3481
- onClick: onDownload,
3482
- className: "p-2 hover:bg-neutral-500 rounded transition-colors",
3483
- "aria-label": "Download PDF",
3484
- type: "button",
3485
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Download, { variant: "dark", className: "w-5 h-5" })
3486
- }
3487
- ),
3488
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3489
- "button",
3490
- {
3491
- onClick: onPrint,
3492
- className: "p-2 hover:bg-neutral-500 rounded transition-colors",
3493
- "aria-label": "Print PDF",
3494
- type: "button",
3495
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Print, { variant: "dark", className: "w-5 h-5" })
3496
- }
3497
- )
3498
- ] })
3499
- ] });
4063
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4064
+ "div",
4065
+ {
4066
+ className: "flex items-center justify-between gap-4 px-4 py-3",
4067
+ style: { background: "#B5B5B5" },
4068
+ children: [
4069
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-shrink min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4070
+ Typography,
4071
+ {
4072
+ variant: "label-md-bold",
4073
+ className: "text-dark truncate",
4074
+ title,
4075
+ children: title || "Untitled Document"
4076
+ }
4077
+ ) }),
4078
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
4079
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4080
+ "button",
4081
+ {
4082
+ onClick: onDownload,
4083
+ className: "p-2 hover:bg-neutral-500 rounded transition-colors",
4084
+ "aria-label": "Download PDF",
4085
+ type: "button",
4086
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Download, { variant: "dark", className: "w-5 h-5" })
4087
+ }
4088
+ ),
4089
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4090
+ "button",
4091
+ {
4092
+ onClick: onPrint,
4093
+ className: "p-2 hover:bg-neutral-500 rounded transition-colors",
4094
+ "aria-label": "Print PDF",
4095
+ type: "button",
4096
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Print, { variant: "dark", className: "w-5 h-5" })
4097
+ }
4098
+ )
4099
+ ] })
4100
+ ]
4101
+ }
4102
+ );
3500
4103
  };
3501
4104
  PdfHeader.displayName = "PdfHeader";
3502
4105
 
3503
4106
  // src/components/pdf-viewer/hooks/useContainerWidth.ts
3504
- var React13 = __toESM(require("react"));
4107
+ var React14 = __toESM(require("react"));
3505
4108
  function useContainerWidth(padding = 32) {
3506
- const [containerWidth, setContainerWidth] = React13.useState(0);
3507
- const containerRef = React13.useRef(null);
3508
- const lastWidthRef = React13.useRef(0);
3509
- React13.useEffect(() => {
4109
+ const [containerWidth, setContainerWidth] = React14.useState(0);
4110
+ const containerRef = React14.useRef(null);
4111
+ const lastWidthRef = React14.useRef(0);
4112
+ React14.useEffect(() => {
3510
4113
  const element = containerRef.current;
3511
4114
  if (!element) return;
3512
4115
  const resizeObserver = new ResizeObserver((entries) => {
@@ -3529,10 +4132,142 @@ function useContainerWidth(padding = 32) {
3529
4132
  return { containerWidth, containerRef };
3530
4133
  }
3531
4134
 
4135
+ // src/components/pdf-viewer/hooks/usePageNavigation.ts
4136
+ var React15 = __toESM(require("react"));
4137
+ function usePageNavigation({
4138
+ containerRef,
4139
+ numPages,
4140
+ onBeforeScroll,
4141
+ page: controlledPage,
4142
+ onPageChange,
4143
+ scrollBehavior = "smooth"
4144
+ }) {
4145
+ const [internalPage, setInternalPage] = React15.useState(1);
4146
+ const pageRefsMap = React15.useRef(/* @__PURE__ */ new Map());
4147
+ const isProgrammaticScroll = React15.useRef(false);
4148
+ const lastScrolledPageRef = React15.useRef(null);
4149
+ const scrollDebounceRef = React15.useRef(
4150
+ null
4151
+ );
4152
+ const isControlled = controlledPage !== void 0;
4153
+ const currentPage = isControlled ? controlledPage : internalPage;
4154
+ const registerPageRef = React15.useCallback(
4155
+ (pageNum, el) => {
4156
+ if (el) {
4157
+ pageRefsMap.current.set(pageNum, el);
4158
+ } else {
4159
+ pageRefsMap.current.delete(pageNum);
4160
+ }
4161
+ },
4162
+ []
4163
+ );
4164
+ const updateCurrentPageFromScroll = React15.useCallback(() => {
4165
+ if (isProgrammaticScroll.current) return;
4166
+ const container = containerRef.current;
4167
+ if (!container || numPages === 0) return;
4168
+ const containerRect = container.getBoundingClientRect();
4169
+ let mostVisiblePage = 1;
4170
+ let maxVisibleArea = 0;
4171
+ for (let pageNum = 1; pageNum <= numPages; pageNum++) {
4172
+ const pageElement = pageRefsMap.current.get(pageNum);
4173
+ if (!pageElement) continue;
4174
+ const pageRect = pageElement.getBoundingClientRect();
4175
+ if (pageRect.bottom > containerRect.top && pageRect.top < containerRect.bottom) {
4176
+ const visibleTop = Math.max(pageRect.top, containerRect.top);
4177
+ const visibleBottom = Math.min(pageRect.bottom, containerRect.bottom);
4178
+ const visibleArea = visibleBottom - visibleTop;
4179
+ if (visibleArea > maxVisibleArea) {
4180
+ maxVisibleArea = visibleArea;
4181
+ mostVisiblePage = pageNum;
4182
+ }
4183
+ }
4184
+ }
4185
+ if (maxVisibleArea > 0) {
4186
+ lastScrolledPageRef.current = mostVisiblePage;
4187
+ if (isControlled) {
4188
+ onPageChange?.(mostVisiblePage);
4189
+ } else {
4190
+ setInternalPage(mostVisiblePage);
4191
+ }
4192
+ }
4193
+ }, [containerRef, numPages, isControlled, onPageChange]);
4194
+ const scrollToPage = React15.useCallback(
4195
+ (pageNum) => {
4196
+ const container = containerRef.current;
4197
+ if (!container) return;
4198
+ onBeforeScroll?.(pageNum);
4199
+ if (scrollDebounceRef.current) {
4200
+ clearTimeout(scrollDebounceRef.current);
4201
+ }
4202
+ const performScroll = () => {
4203
+ isProgrammaticScroll.current = true;
4204
+ requestAnimationFrame(() => {
4205
+ requestAnimationFrame(() => {
4206
+ const pageElement = pageRefsMap.current.get(pageNum);
4207
+ if (container && pageElement) {
4208
+ const containerTop = container.getBoundingClientRect().top;
4209
+ const pageTop = pageElement.getBoundingClientRect().top;
4210
+ const scrollOffset = pageTop - containerTop + container.scrollTop;
4211
+ container.scrollTo({
4212
+ top: scrollOffset,
4213
+ behavior: scrollBehavior
4214
+ });
4215
+ }
4216
+ });
4217
+ });
4218
+ };
4219
+ if (scrollBehavior === "smooth") {
4220
+ scrollDebounceRef.current = setTimeout(performScroll, 100);
4221
+ } else {
4222
+ performScroll();
4223
+ }
4224
+ },
4225
+ [containerRef, onBeforeScroll, scrollBehavior]
4226
+ );
4227
+ const handlePageChange = React15.useCallback(
4228
+ (pageNum) => {
4229
+ const clampedPage = Math.max(1, Math.min(pageNum, numPages));
4230
+ lastScrolledPageRef.current = clampedPage;
4231
+ if (isControlled) {
4232
+ onPageChange?.(clampedPage);
4233
+ } else {
4234
+ setInternalPage(clampedPage);
4235
+ }
4236
+ scrollToPage(clampedPage);
4237
+ },
4238
+ [numPages, scrollToPage, isControlled, onPageChange]
4239
+ );
4240
+ React15.useEffect(() => {
4241
+ if (!isControlled || !controlledPage || numPages <= 0) {
4242
+ return;
4243
+ }
4244
+ if (lastScrolledPageRef.current !== controlledPage) {
4245
+ lastScrolledPageRef.current = controlledPage;
4246
+ scrollToPage(controlledPage);
4247
+ }
4248
+ }, [controlledPage, isControlled, numPages, scrollToPage]);
4249
+ React15.useEffect(() => {
4250
+ return () => {
4251
+ if (scrollDebounceRef.current) {
4252
+ clearTimeout(scrollDebounceRef.current);
4253
+ }
4254
+ };
4255
+ }, []);
4256
+ return {
4257
+ currentPage,
4258
+ registerPageRef,
4259
+ handlePageChange,
4260
+ updateCurrentPageFromScroll,
4261
+ isProgrammaticScroll,
4262
+ pageRefsMap,
4263
+ scrollToPage
4264
+ };
4265
+ }
4266
+
3532
4267
  // src/components/pdf-viewer/hooks/usePdfDownload.ts
3533
- var React14 = __toESM(require("react"));
4268
+ var React16 = __toESM(require("react"));
3534
4269
  function usePdfDownload(file, title) {
3535
- const download = React14.useCallback(async () => {
4270
+ const download = React16.useCallback(async () => {
3536
4271
  if (!file) return;
3537
4272
  try {
3538
4273
  let blob;
@@ -3564,11 +4299,11 @@ function usePdfDownload(file, title) {
3564
4299
  }
3565
4300
 
3566
4301
  // src/components/pdf-viewer/hooks/usePdfPrint.ts
3567
- var React15 = __toESM(require("react"));
4302
+ var React17 = __toESM(require("react"));
3568
4303
  function usePdfPrint(file) {
3569
- const [printBlobUrl, setPrintBlobUrl] = React15.useState(null);
3570
- const printFrameRef = React15.useRef(null);
3571
- const preparePrint = React15.useCallback(async () => {
4304
+ const [printBlobUrl, setPrintBlobUrl] = React17.useState(null);
4305
+ const printFrameRef = React17.useRef(null);
4306
+ const preparePrint = React17.useCallback(async () => {
3572
4307
  if (!file) return;
3573
4308
  try {
3574
4309
  let blob;
@@ -3584,14 +4319,14 @@ function usePdfPrint(file) {
3584
4319
  console.error("Failed to prepare PDF for printing:", error);
3585
4320
  }
3586
4321
  }, [file]);
3587
- React15.useEffect(() => {
4322
+ React17.useEffect(() => {
3588
4323
  return () => {
3589
4324
  if (printBlobUrl) {
3590
4325
  URL.revokeObjectURL(printBlobUrl);
3591
4326
  }
3592
4327
  };
3593
4328
  }, [printBlobUrl]);
3594
- const print = React15.useCallback(() => {
4329
+ const print = React17.useCallback(() => {
3595
4330
  if (printFrameRef.current?.contentWindow) {
3596
4331
  printFrameRef.current.contentWindow.print();
3597
4332
  }
@@ -3599,6 +4334,53 @@ function usePdfPrint(file) {
3599
4334
  return { printFrameRef, printBlobUrl, preparePrint, print };
3600
4335
  }
3601
4336
 
4337
+ // src/components/pdf-viewer/hooks/useZoomControl.ts
4338
+ var React18 = __toESM(require("react"));
4339
+ function useZoomControl({
4340
+ containerRef,
4341
+ initialZoom = PDF_ZOOM.DEFAULT
4342
+ }) {
4343
+ const [zoom, setZoom] = React18.useState(initialZoom);
4344
+ const scrollRatioRef = React18.useRef({ x: 0.5, y: 0 });
4345
+ const handleZoomChange = React18.useCallback(
4346
+ (newZoom) => {
4347
+ const container = containerRef.current;
4348
+ if (container) {
4349
+ const {
4350
+ scrollLeft,
4351
+ scrollTop,
4352
+ scrollWidth,
4353
+ scrollHeight,
4354
+ clientWidth,
4355
+ clientHeight
4356
+ } = container;
4357
+ scrollRatioRef.current = {
4358
+ x: scrollWidth > clientWidth ? scrollLeft / (scrollWidth - clientWidth) : 0.5,
4359
+ y: scrollHeight > clientHeight ? scrollTop / (scrollHeight - clientHeight) : 0
4360
+ };
4361
+ }
4362
+ setZoom(newZoom);
4363
+ },
4364
+ [containerRef]
4365
+ );
4366
+ React18.useEffect(() => {
4367
+ const container = containerRef.current;
4368
+ if (!container) return;
4369
+ requestAnimationFrame(() => {
4370
+ const { scrollWidth, scrollHeight, clientWidth, clientHeight } = container;
4371
+ const maxScrollLeft = scrollWidth - clientWidth;
4372
+ const maxScrollTop = scrollHeight - clientHeight;
4373
+ if (maxScrollLeft > 0) {
4374
+ container.scrollLeft = scrollRatioRef.current.x * maxScrollLeft;
4375
+ }
4376
+ if (maxScrollTop > 0) {
4377
+ container.scrollTop = scrollRatioRef.current.y * maxScrollTop;
4378
+ }
4379
+ });
4380
+ }, [zoom, containerRef]);
4381
+ return { zoom, handleZoomChange };
4382
+ }
4383
+
3602
4384
  // src/components/pdf-viewer/utils/pdfWorker.ts
3603
4385
  var import_react_pdf2 = require("react-pdf");
3604
4386
  function initializePdfWorker(workerUrl) {
@@ -3606,8 +4388,9 @@ function initializePdfWorker(workerUrl) {
3606
4388
  }
3607
4389
 
3608
4390
  // src/components/pdf-viewer/index.tsx
3609
- var import_jsx_runtime18 = require("react/jsx-runtime");
3610
- var PdfViewer = React16.forwardRef(
4391
+ var import_jsx_runtime20 = require("react/jsx-runtime");
4392
+ var DEFAULT_VIEWPORT_BUFFER = 1;
4393
+ var PdfViewer = React19.forwardRef(
3611
4394
  ({
3612
4395
  file,
3613
4396
  title,
@@ -3617,42 +4400,150 @@ var PdfViewer = React16.forwardRef(
3617
4400
  onLoadSuccess,
3618
4401
  onError,
3619
4402
  enableTextLayer = false,
4403
+ showControls = true,
4404
+ viewportBuffer = DEFAULT_VIEWPORT_BUFFER,
4405
+ page: controlledPage,
4406
+ onPageChange,
4407
+ scrollBehavior = "instant",
4408
+ viewMode = "continuous",
3620
4409
  className,
3621
4410
  ...props
3622
4411
  }, ref) => {
4412
+ const [numPages, setNumPages] = React19.useState(0);
4413
+ const [visiblePages, setVisiblePages] = React19.useState(
4414
+ () => /* @__PURE__ */ new Set([1, 2, 3])
4415
+ );
3623
4416
  const { containerWidth, containerRef } = useContainerWidth();
4417
+ const { zoom, handleZoomChange } = useZoomControl({ containerRef });
3624
4418
  const { printFrameRef, printBlobUrl, preparePrint, print } = usePdfPrint(file);
3625
4419
  const download = usePdfDownload(file, title);
3626
- const effectiveWidth = pageWidth || containerWidth;
3627
- const handleLoadSuccess = React16.useCallback(
3628
- async (numPages) => {
3629
- onLoadSuccess?.(numPages);
4420
+ const handleBeforeScroll = React19.useCallback(
4421
+ (pageNum) => {
4422
+ const bufferStart = Math.max(1, pageNum - viewportBuffer);
4423
+ const bufferEnd = Math.min(numPages, pageNum + viewportBuffer);
4424
+ setVisiblePages((prev) => {
4425
+ const merged = new Set(prev);
4426
+ for (let i = bufferStart; i <= bufferEnd; i++) {
4427
+ merged.add(i);
4428
+ }
4429
+ return merged;
4430
+ });
4431
+ },
4432
+ [numPages, viewportBuffer]
4433
+ );
4434
+ const {
4435
+ currentPage,
4436
+ registerPageRef,
4437
+ handlePageChange,
4438
+ updateCurrentPageFromScroll,
4439
+ isProgrammaticScroll,
4440
+ pageRefsMap
4441
+ } = usePageNavigation({
4442
+ containerRef,
4443
+ numPages,
4444
+ onBeforeScroll: handleBeforeScroll,
4445
+ page: controlledPage,
4446
+ onPageChange,
4447
+ scrollBehavior
4448
+ });
4449
+ const baseWidth = Math.min(pageWidth || containerWidth, 800);
4450
+ const effectiveWidth = Math.round(baseWidth * (zoom / 100));
4451
+ const updateVisiblePages = React19.useCallback(() => {
4452
+ if (isProgrammaticScroll.current) return;
4453
+ const container = containerRef.current;
4454
+ if (!container || numPages === 0) return;
4455
+ const containerRect = container.getBoundingClientRect();
4456
+ let firstVisiblePage = -1;
4457
+ let lastVisiblePage = -1;
4458
+ for (let pageNum = 1; pageNum <= numPages; pageNum++) {
4459
+ const pageElement = pageRefsMap.current.get(pageNum);
4460
+ if (!pageElement) continue;
4461
+ const pageRect = pageElement.getBoundingClientRect();
4462
+ if (pageRect.bottom > containerRect.top && pageRect.top < containerRect.bottom) {
4463
+ if (firstVisiblePage === -1) firstVisiblePage = pageNum;
4464
+ lastVisiblePage = pageNum;
4465
+ }
4466
+ }
4467
+ if (firstVisiblePage !== -1) {
4468
+ const bufferStart = Math.max(1, firstVisiblePage - viewportBuffer);
4469
+ const bufferEnd = Math.min(numPages, lastVisiblePage + viewportBuffer);
4470
+ const newVisiblePages = /* @__PURE__ */ new Set();
4471
+ for (let i = bufferStart; i <= bufferEnd; i++) {
4472
+ newVisiblePages.add(i);
4473
+ }
4474
+ setVisiblePages((prev) => {
4475
+ if (prev.size !== newVisiblePages.size) return newVisiblePages;
4476
+ for (const p of prev) {
4477
+ if (!newVisiblePages.has(p)) return newVisiblePages;
4478
+ }
4479
+ return prev;
4480
+ });
4481
+ }
4482
+ }, [
4483
+ containerRef,
4484
+ numPages,
4485
+ viewportBuffer,
4486
+ isProgrammaticScroll,
4487
+ pageRefsMap
4488
+ ]);
4489
+ React19.useEffect(() => {
4490
+ const container = containerRef.current;
4491
+ if (!container) return;
4492
+ let rafId = null;
4493
+ const handleScroll = () => {
4494
+ if (rafId) return;
4495
+ rafId = requestAnimationFrame(() => {
4496
+ updateCurrentPageFromScroll();
4497
+ updateVisiblePages();
4498
+ rafId = null;
4499
+ });
4500
+ };
4501
+ const handleScrollEnd = () => {
4502
+ isProgrammaticScroll.current = false;
4503
+ };
4504
+ container.addEventListener("scroll", handleScroll, { passive: true });
4505
+ container.addEventListener("scrollend", handleScrollEnd);
4506
+ return () => {
4507
+ container.removeEventListener("scroll", handleScroll);
4508
+ container.removeEventListener("scrollend", handleScrollEnd);
4509
+ if (rafId) cancelAnimationFrame(rafId);
4510
+ };
4511
+ }, [
4512
+ updateCurrentPageFromScroll,
4513
+ updateVisiblePages,
4514
+ containerRef,
4515
+ isProgrammaticScroll
4516
+ ]);
4517
+ const handleLoadSuccess = React19.useCallback(
4518
+ async (pages) => {
4519
+ setNumPages(pages);
4520
+ onLoadSuccess?.(pages);
3630
4521
  await preparePrint();
3631
4522
  },
3632
4523
  [onLoadSuccess, preparePrint]
3633
4524
  );
3634
- const handleDownload = React16.useCallback(() => {
4525
+ const handleDownload = React19.useCallback(() => {
3635
4526
  if (onDownload) {
3636
4527
  onDownload();
3637
4528
  return;
3638
4529
  }
3639
4530
  download();
3640
4531
  }, [onDownload, download]);
3641
- const handlePrint = React16.useCallback(() => {
4532
+ const handlePrint = React19.useCallback(() => {
3642
4533
  if (onPrint) {
3643
4534
  onPrint();
3644
4535
  return;
3645
4536
  }
3646
4537
  print();
3647
4538
  }, [onPrint, print]);
3648
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4539
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3649
4540
  "div",
3650
4541
  {
3651
4542
  ref,
3652
4543
  className: cn("h-full flex flex-col", className),
3653
4544
  ...props,
3654
4545
  children: [
3655
- printBlobUrl && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4546
+ printBlobUrl && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3656
4547
  "iframe",
3657
4548
  {
3658
4549
  ref: printFrameRef,
@@ -3661,7 +4552,7 @@ var PdfViewer = React16.forwardRef(
3661
4552
  title: "PDF for printing"
3662
4553
  }
3663
4554
  ),
3664
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4555
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3665
4556
  PdfHeader,
3666
4557
  {
3667
4558
  title,
@@ -3669,23 +4560,35 @@ var PdfViewer = React16.forwardRef(
3669
4560
  onPrint: handlePrint
3670
4561
  }
3671
4562
  ),
3672
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3673
- "div",
3674
- {
3675
- ref: containerRef,
3676
- className: "flex-1 overflow-y-auto overflow-x-hidden bg-neutral-300",
3677
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3678
- PdfDocument,
3679
- {
3680
- file,
3681
- pageWidth: effectiveWidth,
3682
- enableTextLayer,
3683
- onLoadSuccess: handleLoadSuccess,
3684
- onLoadError: onError
3685
- }
3686
- )
3687
- }
3688
- )
4563
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 flex overflow-hidden min-h-0", children: [
4564
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CustomScrollbar, { containerRef, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4565
+ PdfDocument,
4566
+ {
4567
+ file,
4568
+ pageWidth: effectiveWidth,
4569
+ enableTextLayer,
4570
+ onLoadSuccess: handleLoadSuccess,
4571
+ onLoadError: onError,
4572
+ numPages,
4573
+ registerPageRef,
4574
+ visiblePages,
4575
+ viewMode,
4576
+ currentPage
4577
+ }
4578
+ ) }),
4579
+ showControls && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4580
+ PdfControls,
4581
+ {
4582
+ currentPage,
4583
+ totalPages: numPages,
4584
+ onPageChange: handlePageChange,
4585
+ onPreviousPage: () => handlePageChange(currentPage - 1),
4586
+ onNextPage: () => handlePageChange(currentPage + 1),
4587
+ zoom,
4588
+ onZoomChange: handleZoomChange
4589
+ }
4590
+ )
4591
+ ] })
3689
4592
  ]
3690
4593
  }
3691
4594
  );
@@ -3694,9 +4597,9 @@ var PdfViewer = React16.forwardRef(
3694
4597
  PdfViewer.displayName = "PdfViewer";
3695
4598
 
3696
4599
  // src/components/ui/tabs.tsx
3697
- var React17 = __toESM(require("react"));
4600
+ var React20 = __toESM(require("react"));
3698
4601
  var import_class_variance_authority9 = require("class-variance-authority");
3699
- var import_jsx_runtime19 = require("react/jsx-runtime");
4602
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3700
4603
  var tabsVariants = (0, import_class_variance_authority9.cva)(
3701
4604
  "inline-flex items-center justify-start whitespace-nowrap transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-interactive focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 h-10",
3702
4605
  {
@@ -3710,17 +4613,17 @@ var tabsVariants = (0, import_class_variance_authority9.cva)(
3710
4613
  }
3711
4614
  }
3712
4615
  );
3713
- var TabsContext = React17.createContext(
4616
+ var TabsContext = React20.createContext(
3714
4617
  void 0
3715
4618
  );
3716
4619
  function useTabsContext() {
3717
- const context = React17.useContext(TabsContext);
4620
+ const context = React20.useContext(TabsContext);
3718
4621
  if (!context) {
3719
4622
  throw new Error("Tabs components must be used within a Tabs provider");
3720
4623
  }
3721
4624
  return context;
3722
4625
  }
3723
- var Tabs = React17.forwardRef((props, ref) => {
4626
+ var Tabs = React20.forwardRef((props, ref) => {
3724
4627
  const {
3725
4628
  className,
3726
4629
  value,
@@ -3729,7 +4632,7 @@ var Tabs = React17.forwardRef((props, ref) => {
3729
4632
  children,
3730
4633
  ...restProps
3731
4634
  } = props;
3732
- const contextValue = React17.useMemo(
4635
+ const contextValue = React20.useMemo(
3733
4636
  () => ({
3734
4637
  activeTab: value,
3735
4638
  setActiveTab: onValueChange,
@@ -3737,13 +4640,13 @@ var Tabs = React17.forwardRef((props, ref) => {
3737
4640
  }),
3738
4641
  [value, onValueChange, variant]
3739
4642
  );
3740
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref, className: cn("w-full", className), ...restProps, children }) });
4643
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TabsContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref, className: cn("w-full", className), ...restProps, children }) });
3741
4644
  });
3742
4645
  Tabs.displayName = "Tabs";
3743
- var TabsList = React17.forwardRef(
4646
+ var TabsList = React20.forwardRef(
3744
4647
  (props, ref) => {
3745
4648
  const { className, children, ...restProps } = props;
3746
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4649
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3747
4650
  "div",
3748
4651
  {
3749
4652
  ref,
@@ -3759,7 +4662,7 @@ TabsList.displayName = "TabsList";
3759
4662
  var getTabTypographyStyles = (isActive) => ({
3760
4663
  font: isActive ? "var(--typography-label-sm-bold)" : "var(--typography-label-sm-regular)"
3761
4664
  });
3762
- var TabsTrigger = React17.forwardRef(
4665
+ var TabsTrigger = React20.forwardRef(
3763
4666
  (props, ref) => {
3764
4667
  const { className, value, disabled, style, children, ...restProps } = props;
3765
4668
  const { activeTab, setActiveTab, variant } = useTabsContext();
@@ -3767,22 +4670,22 @@ var TabsTrigger = React17.forwardRef(
3767
4670
  throw new Error("TabsTrigger must have a value prop");
3768
4671
  }
3769
4672
  const isActive = activeTab === value;
3770
- const tokenStyles = React17.useMemo(
4673
+ const tokenStyles = React20.useMemo(
3771
4674
  () => ({
3772
4675
  ...getTabTypographyStyles(isActive),
3773
4676
  ...style
3774
4677
  }),
3775
4678
  [isActive, style]
3776
4679
  );
3777
- const triggerClassName = React17.useMemo(
4680
+ const triggerClassName = React20.useMemo(
3778
4681
  () => cn(tabsVariants({ variant }), className),
3779
4682
  [variant, className]
3780
4683
  );
3781
- const handleClick = React17.useCallback(() => {
4684
+ const handleClick = React20.useCallback(() => {
3782
4685
  if (disabled) return;
3783
4686
  setActiveTab(value);
3784
4687
  }, [disabled, setActiveTab, value]);
3785
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4688
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3786
4689
  "button",
3787
4690
  {
3788
4691
  ref,
@@ -3796,13 +4699,13 @@ var TabsTrigger = React17.forwardRef(
3796
4699
  disabled,
3797
4700
  onClick: handleClick,
3798
4701
  ...restProps,
3799
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "pl-3 pr-6 py-2", children })
4702
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "pl-3 pr-6 py-2", children })
3800
4703
  }
3801
4704
  );
3802
4705
  }
3803
4706
  );
3804
4707
  TabsTrigger.displayName = "TabsTrigger";
3805
- var TabsContent = React17.forwardRef(
4708
+ var TabsContent = React20.forwardRef(
3806
4709
  (props, ref) => {
3807
4710
  const { className, value, children, ...restProps } = props;
3808
4711
  const { activeTab } = useTabsContext();
@@ -3813,7 +4716,7 @@ var TabsContent = React17.forwardRef(
3813
4716
  if (!isActive) {
3814
4717
  return null;
3815
4718
  }
3816
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4719
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3817
4720
  "div",
3818
4721
  {
3819
4722
  ref,
@@ -3831,11 +4734,11 @@ var TabsContent = React17.forwardRef(
3831
4734
  TabsContent.displayName = "TabsContent";
3832
4735
 
3833
4736
  // src/components/ui/dropdown-menu.tsx
3834
- var React18 = __toESM(require("react"));
4737
+ var React21 = __toESM(require("react"));
3835
4738
  var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
3836
- var import_jsx_runtime20 = require("react/jsx-runtime");
4739
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3837
4740
  var DropdownMenu = DropdownMenuPrimitive.Root;
3838
- var DropdownMenuTrigger = React18.forwardRef(({ className, icon, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4741
+ var DropdownMenuTrigger = React21.forwardRef(({ className, icon, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3839
4742
  DropdownMenuPrimitive.Trigger,
3840
4743
  {
3841
4744
  ref,
@@ -3845,7 +4748,7 @@ var DropdownMenuTrigger = React18.forwardRef(({ className, icon, children, ...pr
3845
4748
  ),
3846
4749
  ...props,
3847
4750
  children: [
3848
- icon || /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(MoreMenu, { className: "size-4" }),
4751
+ icon || /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MoreMenu, { className: "size-4" }),
3849
4752
  children
3850
4753
  ]
3851
4754
  }
@@ -3855,7 +4758,7 @@ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
3855
4758
  var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
3856
4759
  var DropdownMenuSub = DropdownMenuPrimitive.Sub;
3857
4760
  var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
3858
- var DropdownMenuSubTrigger = React18.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4761
+ var DropdownMenuSubTrigger = React21.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3859
4762
  DropdownMenuPrimitive.SubTrigger,
3860
4763
  {
3861
4764
  ref,
@@ -3868,12 +4771,12 @@ var DropdownMenuSubTrigger = React18.forwardRef(({ className, inset, children, .
3868
4771
  ...props,
3869
4772
  children: [
3870
4773
  children,
3871
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronRight, { className: "ml-auto" })
4774
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ChevronRight, { className: "ml-auto" })
3872
4775
  ]
3873
4776
  }
3874
4777
  ));
3875
4778
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
3876
- var DropdownMenuSubContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4779
+ var DropdownMenuSubContent = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3877
4780
  DropdownMenuPrimitive.SubContent,
3878
4781
  {
3879
4782
  ref,
@@ -3885,7 +4788,7 @@ var DropdownMenuSubContent = React18.forwardRef(({ className, ...props }, ref) =
3885
4788
  }
3886
4789
  ));
3887
4790
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
3888
- var DropdownMenuContent = React18.forwardRef(({ className, sideOffset = 4, align = "end", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4791
+ var DropdownMenuContent = React21.forwardRef(({ className, sideOffset = 4, align = "end", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3889
4792
  DropdownMenuPrimitive.Content,
3890
4793
  {
3891
4794
  ref,
@@ -3899,7 +4802,7 @@ var DropdownMenuContent = React18.forwardRef(({ className, sideOffset = 4, align
3899
4802
  }
3900
4803
  ) }));
3901
4804
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
3902
- var DropdownMenuItem = React18.forwardRef(({ className, inset, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4805
+ var DropdownMenuItem = React21.forwardRef(({ className, inset, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3903
4806
  DropdownMenuPrimitive.Item,
3904
4807
  {
3905
4808
  ref,
@@ -3916,7 +4819,7 @@ var DropdownMenuItem = React18.forwardRef(({ className, inset, style, ...props }
3916
4819
  }
3917
4820
  ));
3918
4821
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
3919
- var DropdownMenuCheckboxItem = React18.forwardRef(({ className, children, style, checked, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4822
+ var DropdownMenuCheckboxItem = React21.forwardRef(({ className, children, style, checked, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3920
4823
  DropdownMenuPrimitive.CheckboxItem,
3921
4824
  {
3922
4825
  ref,
@@ -3931,7 +4834,7 @@ var DropdownMenuCheckboxItem = React18.forwardRef(({ className, children, style,
3931
4834
  },
3932
4835
  ...props,
3933
4836
  children: [
3934
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4837
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3935
4838
  Checkbox,
3936
4839
  {
3937
4840
  checked: checked === true,
@@ -3939,12 +4842,12 @@ var DropdownMenuCheckboxItem = React18.forwardRef(({ className, children, style,
3939
4842
  "aria-hidden": "true"
3940
4843
  }
3941
4844
  ),
3942
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1", children })
4845
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex-1", children })
3943
4846
  ]
3944
4847
  }
3945
4848
  ));
3946
4849
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
3947
- var DropdownMenuRadioItem = React18.forwardRef(({ className, children, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4850
+ var DropdownMenuRadioItem = React21.forwardRef(({ className, children, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3948
4851
  DropdownMenuPrimitive.RadioItem,
3949
4852
  {
3950
4853
  ref,
@@ -3958,13 +4861,13 @@ var DropdownMenuRadioItem = React18.forwardRef(({ className, children, style, ..
3958
4861
  },
3959
4862
  ...props,
3960
4863
  children: [
3961
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "h-2 w-2 rounded-full bg-current" }) }) }),
4864
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-2 w-2 rounded-full bg-current" }) }) }),
3962
4865
  children
3963
4866
  ]
3964
4867
  }
3965
4868
  ));
3966
4869
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
3967
- var DropdownMenuLabel = React18.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4870
+ var DropdownMenuLabel = React21.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3968
4871
  DropdownMenuPrimitive.Label,
3969
4872
  {
3970
4873
  ref,
@@ -3977,7 +4880,7 @@ var DropdownMenuLabel = React18.forwardRef(({ className, inset, ...props }, ref)
3977
4880
  }
3978
4881
  ));
3979
4882
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
3980
- var DropdownMenuSeparator = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4883
+ var DropdownMenuSeparator = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3981
4884
  DropdownMenuPrimitive.Separator,
3982
4885
  {
3983
4886
  ref,
@@ -3990,7 +4893,7 @@ var DropdownMenuShortcut = ({
3990
4893
  className,
3991
4894
  ...props
3992
4895
  }) => {
3993
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4896
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3994
4897
  "span",
3995
4898
  {
3996
4899
  className: cn("ml-auto text-xs tracking-widest opacity-60", className),
@@ -4001,21 +4904,21 @@ var DropdownMenuShortcut = ({
4001
4904
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
4002
4905
 
4003
4906
  // src/components/ui/charts/chart-legend.tsx
4004
- var import_jsx_runtime21 = require("react/jsx-runtime");
4907
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4005
4908
  function ChartLegend({
4006
4909
  items,
4007
4910
  x = 0,
4008
4911
  y = 550,
4009
4912
  className = ""
4010
4913
  }) {
4011
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("foreignObject", { x, y, width: "100%", height: "40", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4914
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("foreignObject", { x, y, width: "100%", height: "40", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4012
4915
  "div",
4013
4916
  {
4014
4917
  className: `flex justify-center items-center gap-6 ${className}`,
4015
4918
  style: { height: "100%" },
4016
- children: items.map(({ key, color, label }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
4017
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-3 h-3", style: { backgroundColor: color } }),
4018
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Typography, { variant: "body-xs", children: label || key })
4919
+ children: items.map(({ key, color, label }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
4920
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-3 h-3", style: { backgroundColor: color } }),
4921
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Typography, { variant: "body-xs", children: label || key })
4019
4922
  ] }, key))
4020
4923
  }
4021
4924
  ) });
@@ -4133,12 +5036,12 @@ var formatLargeNumber = (value) => {
4133
5036
  };
4134
5037
 
4135
5038
  // src/components/ui/charts/chart-labels.tsx
4136
- var import_jsx_runtime22 = require("react/jsx-runtime");
5039
+ var import_jsx_runtime24 = require("react/jsx-runtime");
4137
5040
  var createCustomXAxisLabel = (text, yOffset = 40) => {
4138
5041
  const CustomXAxisLabel = ({ viewBox }) => {
4139
5042
  if (!viewBox) return null;
4140
5043
  const { x, y, width } = viewBox;
4141
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("foreignObject", { x, y: y + yOffset, width, height: 20, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex justify-center w-full", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Typography, { variant: "label-xs-bold", className: "text-secondary", children: text }) }) }) });
5044
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("foreignObject", { x, y: y + yOffset, width, height: 20, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex justify-center w-full", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Typography, { variant: "label-xs-bold", className: "text-secondary", children: text }) }) }) });
4142
5045
  };
4143
5046
  CustomXAxisLabel.displayName = "CustomXAxisLabel";
4144
5047
  return CustomXAxisLabel;
@@ -4148,7 +5051,7 @@ var createCustomYAxisLabel = (text, leftMargin) => {
4148
5051
  if (!viewBox) return null;
4149
5052
  const { x, y, height } = viewBox;
4150
5053
  const offset = leftMargin ? leftMargin + 10 : 110;
4151
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("foreignObject", { x: x - offset, y, width: 100, height, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex items-center justify-center h-full transform -rotate-90 whitespace-nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Typography, { variant: "label-xs-bold", className: "text-secondary", children: text }) }) }) });
5054
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("foreignObject", { x: x - offset, y, width: 100, height, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-center h-full transform -rotate-90 whitespace-nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Typography, { variant: "label-xs-bold", className: "text-secondary", children: text }) }) }) });
4152
5055
  };
4153
5056
  CustomYAxisLabel.displayName = "CustomYAxisLabel";
4154
5057
  return CustomYAxisLabel;
@@ -4157,14 +5060,14 @@ var createCustomYAxisRightLabel = (text) => {
4157
5060
  const CustomYAxisRightLabel = ({ viewBox }) => {
4158
5061
  if (!viewBox) return null;
4159
5062
  const { x, y, width, height } = viewBox;
4160
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("foreignObject", { x: x + width - 70, y, width: 120, height, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex items-center justify-center h-full transform rotate-90 whitespace-nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Typography, { variant: "label-xs-bold", className: "text-secondary", children: text }) }) }) });
5063
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("foreignObject", { x: x + width - 70, y, width: 120, height, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-center h-full transform rotate-90 whitespace-nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Typography, { variant: "label-xs-bold", className: "text-secondary", children: text }) }) }) });
4161
5064
  };
4162
5065
  CustomYAxisRightLabel.displayName = "CustomYAxisRightLabel";
4163
5066
  return CustomYAxisRightLabel;
4164
5067
  };
4165
5068
  var customXAxisTick = (props) => {
4166
5069
  const { x, y, payload } = props;
4167
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5070
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4168
5071
  "foreignObject",
4169
5072
  {
4170
5073
  x: -20,
@@ -4172,12 +5075,12 @@ var customXAxisTick = (props) => {
4172
5075
  width: 40,
4173
5076
  height: 20,
4174
5077
  style: { overflow: "visible" },
4175
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5078
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4176
5079
  "div",
4177
5080
  {
4178
5081
  className: "flex items-start justify-center h-full",
4179
5082
  style: { overflow: "visible" },
4180
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5083
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4181
5084
  Typography,
4182
5085
  {
4183
5086
  variant: "body-xs",
@@ -4192,7 +5095,7 @@ var customXAxisTick = (props) => {
4192
5095
  };
4193
5096
  var customXAxisTickRotated = (props) => {
4194
5097
  const { x, y, payload } = props;
4195
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5098
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4196
5099
  "text",
4197
5100
  {
4198
5101
  x: 0,
@@ -4211,25 +5114,25 @@ var customYAxisTick = (props) => {
4211
5114
  const { x, y, payload } = props;
4212
5115
  const text = String(payload.value);
4213
5116
  const estimatedWidth = Math.max(text.length * 8, 80);
4214
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5117
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4215
5118
  "foreignObject",
4216
5119
  {
4217
5120
  x: x - estimatedWidth + 5,
4218
5121
  y: y - 6,
4219
5122
  width: estimatedWidth,
4220
5123
  height: 15,
4221
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex justify-end w-full", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Typography, { variant: "body-xs", className: "text-secondary", children: payload.value }) })
5124
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex justify-end w-full", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Typography, { variant: "body-xs", className: "text-secondary", children: payload.value }) })
4222
5125
  }
4223
5126
  );
4224
5127
  };
4225
5128
 
4226
5129
  // src/components/ui/charts/chart-tooltip.tsx
4227
- var import_jsx_runtime23 = require("react/jsx-runtime");
5130
+ var import_jsx_runtime25 = require("react/jsx-runtime");
4228
5131
  function TooltipContainer({
4229
5132
  children,
4230
5133
  className = ""
4231
5134
  }) {
4232
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5135
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4233
5136
  "div",
4234
5137
  {
4235
5138
  className: `bg-light border border-subtle rounded p-2.5 text-dark ${className}`,
@@ -4243,10 +5146,10 @@ function TooltipItem({
4243
5146
  value,
4244
5147
  className = ""
4245
5148
  }) {
4246
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4247
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("br", {}),
4248
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Typography, { variant: "label-sm", className, children: [
4249
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5149
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5150
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("br", {}),
5151
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Typography, { variant: "label-sm", className, children: [
5152
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4250
5153
  "span",
4251
5154
  {
4252
5155
  className: "inline-block w-3 h-3 mr-1.5",
@@ -4264,9 +5167,9 @@ function GenericTooltip({
4264
5167
  items,
4265
5168
  className = ""
4266
5169
  }) {
4267
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(TooltipContainer, { className, children: [
4268
- title && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Typography, { variant: "label-sm-bold", children: title }),
4269
- items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5170
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(TooltipContainer, { className, children: [
5171
+ title && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Typography, { variant: "label-sm-bold", children: title }),
5172
+ items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4270
5173
  TooltipItem,
4271
5174
  {
4272
5175
  color: item.color,
@@ -4281,7 +5184,7 @@ function GenericTooltip({
4281
5184
  // src/components/ui/charts/bar-chart.tsx
4282
5185
  var import_react2 = require("react");
4283
5186
  var import_recharts = require("recharts");
4284
- var import_jsx_runtime24 = require("react/jsx-runtime");
5187
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4285
5188
  var BarChart = (0, import_react2.forwardRef)(
4286
5189
  ({
4287
5190
  data,
@@ -4308,19 +5211,19 @@ var BarChart = (0, import_react2.forwardRef)(
4308
5211
  };
4309
5212
  const defaultLegendItems = showLegend && legendItems.length === 0 ? [{ key: yAxisKey, color: barColor, label: yAxisKey }] : legendItems;
4310
5213
  const hasData = data && data.length > 0;
4311
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5214
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4312
5215
  "div",
4313
5216
  {
4314
5217
  ref,
4315
5218
  className: `bg-light border border-subtle mx-6 ${className}`,
4316
5219
  children: [
4317
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-between px-3 py-2 border-b border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Typography, { variant: "label-sm-bold", children: title }) }),
4318
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "pt-2 px-2", children: hasData ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5220
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-between px-3 py-2 border-b border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Typography, { variant: "label-sm-bold", children: title }) }),
5221
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "pt-2 px-2", children: hasData ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4319
5222
  import_recharts.ResponsiveContainer,
4320
5223
  {
4321
5224
  width: "100%",
4322
5225
  height: CHART_CONSTANTS.STANDARD_HEIGHT,
4323
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5226
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4324
5227
  import_recharts.BarChart,
4325
5228
  {
4326
5229
  data,
@@ -4332,7 +5235,7 @@ var BarChart = (0, import_react2.forwardRef)(
4332
5235
  onClick: handleClick,
4333
5236
  layout,
4334
5237
  children: [
4335
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5238
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4336
5239
  import_recharts.XAxis,
4337
5240
  {
4338
5241
  dataKey: xAxisKey,
@@ -4346,7 +5249,7 @@ var BarChart = (0, import_react2.forwardRef)(
4346
5249
  label: xAxisLabel ? createCustomXAxisLabel(xAxisLabel, 80) : void 0
4347
5250
  }
4348
5251
  ),
4349
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5252
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4350
5253
  import_recharts.YAxis,
4351
5254
  {
4352
5255
  axisLine: false,
@@ -4357,7 +5260,7 @@ var BarChart = (0, import_react2.forwardRef)(
4357
5260
  type: yAxisType
4358
5261
  }
4359
5262
  ),
4360
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5263
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4361
5264
  import_recharts.Tooltip,
4362
5265
  {
4363
5266
  content: ({
@@ -4366,7 +5269,7 @@ var BarChart = (0, import_react2.forwardRef)(
4366
5269
  label
4367
5270
  }) => {
4368
5271
  if (active && payload && payload.length) {
4369
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5272
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4370
5273
  GenericTooltip,
4371
5274
  {
4372
5275
  title: label?.toString(),
@@ -4382,7 +5285,7 @@ var BarChart = (0, import_react2.forwardRef)(
4382
5285
  }
4383
5286
  }
4384
5287
  ),
4385
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5288
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4386
5289
  import_recharts.Bar,
4387
5290
  {
4388
5291
  dataKey: barDataKey || yAxisKey,
@@ -4390,12 +5293,12 @@ var BarChart = (0, import_react2.forwardRef)(
4390
5293
  name: barDataKey || yAxisKey
4391
5294
  }
4392
5295
  ),
4393
- showLegend && defaultLegendItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChartLegend, { items: defaultLegendItems })
5296
+ showLegend && defaultLegendItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ChartLegend, { items: defaultLegendItems })
4394
5297
  ]
4395
5298
  }
4396
5299
  )
4397
5300
  }
4398
- ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-center h-[500px]", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No data is available" }) }) })
5301
+ ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-center h-[500px]", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No data is available" }) }) })
4399
5302
  ]
4400
5303
  }
4401
5304
  );
@@ -4406,7 +5309,7 @@ BarChart.displayName = "BarChart";
4406
5309
  // src/components/ui/charts/line-chart.tsx
4407
5310
  var import_react3 = require("react");
4408
5311
  var import_recharts2 = require("recharts");
4409
- var import_jsx_runtime25 = require("react/jsx-runtime");
5312
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4410
5313
  var LineChart = (0, import_react3.forwardRef)(
4411
5314
  ({
4412
5315
  data,
@@ -4435,19 +5338,19 @@ var LineChart = (0, import_react3.forwardRef)(
4435
5338
  )
4436
5339
  );
4437
5340
  const hasData = data && data.length > 0;
4438
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5341
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4439
5342
  "div",
4440
5343
  {
4441
5344
  ref,
4442
5345
  className: `bg-light border border-subtle mx-6 ${className}`,
4443
5346
  children: [
4444
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center justify-between px-3 py-2 border-b border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Typography, { variant: "label-sm-bold", children: title }) }),
4445
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pt-2 px-2", children: hasData ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5347
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex items-center justify-between px-3 py-2 border-b border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Typography, { variant: "label-sm-bold", children: title }) }),
5348
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "pt-2 px-2", children: hasData ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4446
5349
  import_recharts2.ResponsiveContainer,
4447
5350
  {
4448
5351
  width: "100%",
4449
5352
  height: CHART_CONSTANTS.STANDARD_HEIGHT,
4450
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5353
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4451
5354
  import_recharts2.LineChart,
4452
5355
  {
4453
5356
  data,
@@ -4458,7 +5361,7 @@ var LineChart = (0, import_react3.forwardRef)(
4458
5361
  },
4459
5362
  onClick: handleClick,
4460
5363
  children: [
4461
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5364
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4462
5365
  import_recharts2.XAxis,
4463
5366
  {
4464
5367
  dataKey: xAxisKey,
@@ -4470,7 +5373,7 @@ var LineChart = (0, import_react3.forwardRef)(
4470
5373
  label: xAxisLabel ? createCustomXAxisLabel(xAxisLabel) : void 0
4471
5374
  }
4472
5375
  ),
4473
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5376
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4474
5377
  import_recharts2.YAxis,
4475
5378
  {
4476
5379
  axisLine: false,
@@ -4479,7 +5382,7 @@ var LineChart = (0, import_react3.forwardRef)(
4479
5382
  label: yAxisLabel ? createCustomYAxisLabel(yAxisLabel, 40) : void 0
4480
5383
  }
4481
5384
  ),
4482
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5385
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4483
5386
  import_recharts2.Tooltip,
4484
5387
  {
4485
5388
  content: ({
@@ -4488,7 +5391,7 @@ var LineChart = (0, import_react3.forwardRef)(
4488
5391
  label
4489
5392
  }) => {
4490
5393
  if (active && payload && payload.length) {
4491
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5394
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4492
5395
  GenericTooltip,
4493
5396
  {
4494
5397
  title: label?.toString(),
@@ -4504,7 +5407,7 @@ var LineChart = (0, import_react3.forwardRef)(
4504
5407
  }
4505
5408
  }
4506
5409
  ),
4507
- series.map((s, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5410
+ series.map((s, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4508
5411
  import_recharts2.Line,
4509
5412
  {
4510
5413
  type: "monotone",
@@ -4516,12 +5419,12 @@ var LineChart = (0, import_react3.forwardRef)(
4516
5419
  },
4517
5420
  s.dataKey
4518
5421
  )),
4519
- showLegend && defaultLegendItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ChartLegend, { items: defaultLegendItems })
5422
+ showLegend && defaultLegendItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChartLegend, { items: defaultLegendItems })
4520
5423
  ]
4521
5424
  }
4522
5425
  )
4523
5426
  }
4524
- ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center justify-center h-[500px]", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No data is available" }) }) })
5427
+ ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex items-center justify-center h-[500px]", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No data is available" }) }) })
4525
5428
  ]
4526
5429
  }
4527
5430
  );
@@ -4532,7 +5435,7 @@ LineChart.displayName = "LineChart";
4532
5435
  // src/components/ui/charts/pie-chart.tsx
4533
5436
  var import_react4 = require("react");
4534
5437
  var import_recharts3 = require("recharts");
4535
- var import_jsx_runtime26 = require("react/jsx-runtime");
5438
+ var import_jsx_runtime28 = require("react/jsx-runtime");
4536
5439
  var PieChart = (0, import_react4.forwardRef)(
4537
5440
  ({
4538
5441
  data,
@@ -4560,20 +5463,20 @@ var PieChart = (0, import_react4.forwardRef)(
4560
5463
  )
4561
5464
  );
4562
5465
  const hasData = data && data.length > 0;
4563
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5466
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
4564
5467
  "div",
4565
5468
  {
4566
5469
  ref,
4567
5470
  className: `bg-light border border-subtle mx-6 ${className}`,
4568
5471
  children: [
4569
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-between px-3 py-2 border-b border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Typography, { variant: "label-sm-bold", children: title }) }),
4570
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "pt-2 px-2", children: hasData ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5472
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-between px-3 py-2 border-b border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Typography, { variant: "label-sm-bold", children: title }) }),
5473
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "pt-2 px-2", children: hasData ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
4571
5474
  import_recharts3.PieChart,
4572
5475
  {
4573
5476
  width: 600,
4574
5477
  height: CHART_CONSTANTS.LARGE_HEIGHT,
4575
5478
  children: [
4576
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5479
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4577
5480
  import_recharts3.Pie,
4578
5481
  {
4579
5482
  data,
@@ -4585,7 +5488,7 @@ var PieChart = (0, import_react4.forwardRef)(
4585
5488
  label: showLabels,
4586
5489
  labelLine: false,
4587
5490
  onClick: handleClick,
4588
- children: data.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5491
+ children: data.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4589
5492
  import_recharts3.Cell,
4590
5493
  {
4591
5494
  fill: entry.color || getSeriesColor(index)
@@ -4594,7 +5497,7 @@ var PieChart = (0, import_react4.forwardRef)(
4594
5497
  ))
4595
5498
  }
4596
5499
  ),
4597
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5500
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4598
5501
  import_recharts3.Tooltip,
4599
5502
  {
4600
5503
  content: ({
@@ -4603,7 +5506,7 @@ var PieChart = (0, import_react4.forwardRef)(
4603
5506
  }) => {
4604
5507
  if (active && payload && payload.length && payload[0]) {
4605
5508
  const data2 = payload[0].payload;
4606
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5509
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4607
5510
  GenericTooltip,
4608
5511
  {
4609
5512
  title: data2.name,
@@ -4621,10 +5524,10 @@ var PieChart = (0, import_react4.forwardRef)(
4621
5524
  }
4622
5525
  }
4623
5526
  ),
4624
- showLegend && defaultLegendItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ChartLegend, { items: defaultLegendItems, y: 400 })
5527
+ showLegend && defaultLegendItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChartLegend, { items: defaultLegendItems, y: 400 })
4625
5528
  ]
4626
5529
  }
4627
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-center h-[500px]", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No data is available" }) }) })
5530
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center h-[500px]", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Typography, { variant: "body-md", className: "text-secondary", children: "No data is available" }) }) })
4628
5531
  ]
4629
5532
  }
4630
5533
  );
@@ -4635,7 +5538,7 @@ PieChart.displayName = "PieChart";
4635
5538
  // src/components/ui/table.tsx
4636
5539
  var import_react5 = require("react");
4637
5540
  var import_react_table = require("@tanstack/react-table");
4638
- var import_jsx_runtime27 = require("react/jsx-runtime");
5541
+ var import_jsx_runtime29 = require("react/jsx-runtime");
4639
5542
  function Table({
4640
5543
  table,
4641
5544
  className,
@@ -4665,15 +5568,15 @@ function Table({
4665
5568
  },
4666
5569
  [table]
4667
5570
  );
4668
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
4669
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("overflow-x-auto", className), children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("table", { className: "min-w-full divide-y divide-border", children: [
4670
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("thead", { className: "bg-dark text-light", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("th", { className: "px-6 py-3 text-left", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5571
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
5572
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("overflow-x-auto", className), children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("table", { className: "min-w-full divide-y divide-border", children: [
5573
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("thead", { className: "bg-dark text-light", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("th", { className: "px-6 py-3 text-left", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4671
5574
  "div",
4672
5575
  {
4673
5576
  className: `flex items-center space-x-1 ${header.column.getCanSort() ? "cursor-pointer select-none" : ""}`,
4674
5577
  onClick: header.column.getToggleSortingHandler(),
4675
5578
  children: [
4676
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5579
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4677
5580
  Typography,
4678
5581
  {
4679
5582
  variant: "label-xs",
@@ -4684,19 +5587,19 @@ function Table({
4684
5587
  )
4685
5588
  }
4686
5589
  ),
4687
- header.column.getCanSort() && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "ml-1", children: [
4688
- header.column.getIsSorted() === "asc" && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChevronUp, { className: "w-4 h-4 text-light" }),
4689
- header.column.getIsSorted() === "desc" && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChevronDown, { className: "w-4 h-4 text-light" })
5590
+ header.column.getCanSort() && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "ml-1", children: [
5591
+ header.column.getIsSorted() === "asc" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChevronUp, { className: "w-4 h-4 text-light" }),
5592
+ header.column.getIsSorted() === "desc" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChevronDown, { className: "w-4 h-4 text-light" })
4690
5593
  ] })
4691
5594
  ]
4692
5595
  }
4693
5596
  ) }, header.id)) }, headerGroup.id)) }),
4694
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("tbody", { className: "bg-light divide-y divide-border", children: table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("tr", { children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Typography, { variant: "body-sm", children: (0, import_react_table.flexRender)(
5597
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("tbody", { className: "bg-light divide-y divide-border", children: table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("tr", { children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Typography, { variant: "body-sm", children: (0, import_react_table.flexRender)(
4695
5598
  cell.column.columnDef.cell,
4696
5599
  cell.getContext()
4697
5600
  ) }) }, cell.id)) }, row.id)) })
4698
5601
  ] }) }),
4699
- showPagination && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5602
+ showPagination && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4700
5603
  "div",
4701
5604
  {
4702
5605
  className: cn(
@@ -4704,9 +5607,9 @@ function Table({
4704
5607
  paginationClassName
4705
5608
  ),
4706
5609
  children: [
4707
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Typography, { variant: "body-sm", className: "text-secondary", children: showingText }) }),
4708
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center space-x-1", children: [
4709
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5610
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Typography, { variant: "body-sm", className: "text-secondary", children: showingText }) }),
5611
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center space-x-1", children: [
5612
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4710
5613
  Button,
4711
5614
  {
4712
5615
  variant: "ghost",
@@ -4714,7 +5617,7 @@ function Table({
4714
5617
  onClick: handlePreviousPage,
4715
5618
  disabled: !table.getCanPreviousPage(),
4716
5619
  className: "p-2",
4717
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChevronLeft, { className: "w-4 h-4" })
5620
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChevronLeft, { className: "w-4 h-4" })
4718
5621
  }
4719
5622
  ),
4720
5623
  Array.from(
@@ -4731,7 +5634,7 @@ function Table({
4731
5634
  pageNumber = currentPage - 2 + i;
4732
5635
  }
4733
5636
  const isActive = pageNumber === currentPage;
4734
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5637
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4735
5638
  Button,
4736
5639
  {
4737
5640
  variant: isActive ? "default" : "ghost",
@@ -4744,11 +5647,11 @@ function Table({
4744
5647
  );
4745
5648
  }
4746
5649
  ),
4747
- table.getPageCount() > 5 && currentPage < totalPages - 3 && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
4748
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "px-1 text-secondary", children: "..." }),
4749
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Typography, { variant: "body-sm", className: "text-secondary", children: totalPages })
5650
+ table.getPageCount() > 5 && currentPage < totalPages - 3 && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
5651
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "px-1 text-secondary", children: "..." }),
5652
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Typography, { variant: "body-sm", className: "text-secondary", children: totalPages })
4750
5653
  ] }),
4751
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5654
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4752
5655
  Button,
4753
5656
  {
4754
5657
  variant: "ghost",
@@ -4756,12 +5659,12 @@ function Table({
4756
5659
  onClick: handleNextPage,
4757
5660
  disabled: !table.getCanNextPage(),
4758
5661
  className: "p-2",
4759
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChevronRight, { className: "w-4 h-4" })
5662
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChevronRight, { className: "w-4 h-4" })
4760
5663
  }
4761
5664
  )
4762
5665
  ] }),
4763
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-3 w-48", children: [
4764
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5666
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-3 w-48", children: [
5667
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4765
5668
  Typography,
4766
5669
  {
4767
5670
  variant: "body-sm",
@@ -4769,14 +5672,14 @@ function Table({
4769
5672
  children: "Rows per page:"
4770
5673
  }
4771
5674
  ),
4772
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5675
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
4773
5676
  Select,
4774
5677
  {
4775
5678
  value: table.getState().pagination.pageSize.toString(),
4776
5679
  onValueChange: handlePageSizeChange,
4777
5680
  children: [
4778
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectTrigger, { className: "min-w-0 h-8", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectValue, {}) }),
4779
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectContent, { children: [10, 20, 50, 100].map((size) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SelectItem, { value: size.toString(), children: size }, size)) })
5681
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectTrigger, { className: "min-w-0 h-8", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectValue, {}) }),
5682
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectContent, { children: [10, 20, 50, 100].map((size) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SelectItem, { value: size.toString(), children: size }, size)) })
4780
5683
  ]
4781
5684
  }
4782
5685
  )