@j3m-quantum/ui 1.0.0 → 1.3.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
@@ -1,4 +1,4 @@
1
- import * as React7 from 'react';
1
+ import * as React14 from 'react';
2
2
  import { useMemo } from 'react';
3
3
  import { Slot } from '@radix-ui/react-slot';
4
4
  import { cva } from 'class-variance-authority';
@@ -7,7 +7,7 @@ import { twMerge } from 'tailwind-merge';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
9
9
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
10
- import { CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronLeftIcon, ChevronRightIcon, ArrowLeft, ArrowRight, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, ChevronRight, MoreHorizontal, MoreHorizontalIcon, XIcon, SearchIcon, GripVerticalIcon, PanelLeftIcon } from 'lucide-react';
10
+ import { SearchIcon, CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronRightIcon, ChevronLeftIcon, ArrowLeft, ArrowRight, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, ChevronRight, MoreHorizontal, MoreHorizontalIcon, XIcon, GripVerticalIcon, PanelLeftIcon, FolderIcon, ShareIcon, TrashIcon, ChevronsUpDownIcon, SparklesIcon, BadgeCheckIcon, CreditCardIcon, BellIcon, LogOutIcon, User, Calendar as Calendar$1, Clock, CalendarX2, ChevronLeft, List, Columns, Grid2x2, Grid3x3, CalendarRange, Plus, Info, Moon, Settings } from 'lucide-react';
11
11
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
12
12
  import * as SwitchPrimitive from '@radix-ui/react-switch';
13
13
  import * as SliderPrimitive from '@radix-ui/react-slider';
@@ -17,6 +17,7 @@ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
17
17
  import { FormProvider, Controller, useFormContext, useFormState } from 'react-hook-form';
18
18
  import * as LabelPrimitive from '@radix-ui/react-label';
19
19
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
20
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
20
21
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
21
22
  import * as TabsPrimitive from '@radix-ui/react-tabs';
22
23
  import { getDefaultClassNames, DayPicker } from 'react-day-picker';
@@ -29,7 +30,6 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
29
30
  import { Toaster as Toaster$1 } from 'sonner';
30
31
  import { Command as Command$1 } from 'cmdk';
31
32
  import * as DialogPrimitive from '@radix-ui/react-dialog';
32
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
33
33
  import * as MenubarPrimitive from '@radix-ui/react-menubar';
34
34
  import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
35
35
  import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
@@ -39,12 +39,14 @@ import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
39
39
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
40
40
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
41
41
  import * as ResizablePrimitive from 'react-resizable-panels';
42
+ import { subMonths, subYears, subWeeks, subDays, addMonths, addYears, addWeeks, addDays, format, startOfWeek, endOfWeek, startOfMonth, endOfMonth, startOfYear, endOfYear, isSameMonth, isSameWeek, isSameDay, isSameYear, isWithinInterval, parseISO, differenceInMinutes, eachDayOfInterval, differenceInDays, startOfDay, setMinutes, setHours, eachHourOfInterval, endOfDay, getHours, getMinutes, addMinutes, isToday, areIntervalsOverlapping } from 'date-fns';
43
+ export { areIntervalsOverlapping, format, getDay, isSameDay, isSameMonth, isToday, parseISO } from 'date-fns';
42
44
 
43
45
  // src/hooks/use-mobile.ts
44
46
  var MOBILE_BREAKPOINT = 768;
45
47
  function useIsMobile() {
46
- const [isMobile, setIsMobile] = React7.useState(void 0);
47
- React7.useEffect(() => {
48
+ const [isMobile, setIsMobile] = React14.useState(void 0);
49
+ React14.useEffect(() => {
48
50
  const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
49
51
  const onChange = () => {
50
52
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
@@ -63,10 +65,10 @@ var buttonVariants = cva(
63
65
  {
64
66
  variants: {
65
67
  variant: {
66
- default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
67
- destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
68
- outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
69
- secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
68
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
69
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
70
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
71
+ secondary: "bg-secondary text-secondary-foreground border border-input hover:bg-secondary/80",
70
72
  ghost: "hover:bg-accent hover:text-accent-foreground",
71
73
  link: "text-primary underline-offset-4 hover:underline"
72
74
  },
@@ -85,7 +87,7 @@ var buttonVariants = cva(
85
87
  }
86
88
  }
87
89
  );
88
- var Button = React7.forwardRef(
90
+ var Button = React14.forwardRef(
89
91
  ({ className, variant, size, asChild = false, ...props }, ref) => {
90
92
  const Comp = asChild ? Slot : "button";
91
93
  return /* @__PURE__ */ jsx(
@@ -449,7 +451,7 @@ function Slider({
449
451
  max = 100,
450
452
  ...props
451
453
  }) {
452
- const _values = React7.useMemo(
454
+ const _values = React14.useMemo(
453
455
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
454
456
  [value, defaultValue, min, max]
455
457
  );
@@ -485,7 +487,7 @@ function Slider({
485
487
  )
486
488
  }
487
489
  ),
488
- Array.from({ length: _values.length }, (_2, index) => /* @__PURE__ */ jsx(
490
+ Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ jsx(
489
491
  SliderPrimitive.Thumb,
490
492
  {
491
493
  "data-slot": "slider-thumb",
@@ -735,7 +737,7 @@ function Toggle({
735
737
  }
736
738
  );
737
739
  }
738
- var ToggleGroupContext = React7.createContext({
740
+ var ToggleGroupContext = React14.createContext({
739
741
  size: "default",
740
742
  variant: "default",
741
743
  spacing: 0
@@ -772,7 +774,7 @@ function ToggleGroupItem({
772
774
  size,
773
775
  ...props
774
776
  }) {
775
- const context = React7.useContext(ToggleGroupContext);
777
+ const context = React14.useContext(ToggleGroupContext);
776
778
  return /* @__PURE__ */ jsx(
777
779
  ToggleGroupPrimitive.Item,
778
780
  {
@@ -803,7 +805,7 @@ function ToolBarCanvas({
803
805
  {
804
806
  "data-slot": "toolbar-canvas",
805
807
  className: cn(
806
- "inline-flex items-center gap-1 rounded-full bg-sidebar border border-sidebar-border p-1.5",
808
+ "inline-flex items-center gap-1 rounded-full bg-background border border-input p-1.5",
807
809
  className
808
810
  ),
809
811
  ...props
@@ -898,7 +900,7 @@ function PlayerCanvasControls({
898
900
  {
899
901
  "data-slot": "player-canvas-controls",
900
902
  className: cn(
901
- "flex items-center gap-2 px-1.5 py-1.5 rounded-full bg-sidebar border border-sidebar-border",
903
+ "flex items-center gap-2 px-1.5 py-1.5 rounded-full bg-background border border-input",
902
904
  className
903
905
  ),
904
906
  ...props
@@ -939,7 +941,7 @@ function PlayerCanvasPlayButton({
939
941
  className
940
942
  ),
941
943
  style: {
942
- backgroundColor: "hsl(var(--primary))",
944
+ backgroundColor: "var(--j3m-orange-8)",
943
945
  ...style
944
946
  },
945
947
  ...props,
@@ -1079,7 +1081,7 @@ function PlayerCanvasProgress({
1079
1081
  className: "absolute inset-y-0 left-0 rounded-full transition-all duration-200",
1080
1082
  style: {
1081
1083
  width: `${percentage}%`,
1082
- backgroundColor: "hsl(var(--primary))"
1084
+ backgroundColor: "var(--j3m-orange-8)"
1083
1085
  }
1084
1086
  }
1085
1087
  )
@@ -1103,7 +1105,7 @@ function Label2({
1103
1105
  );
1104
1106
  }
1105
1107
  var Form = FormProvider;
1106
- var FormFieldContext = React7.createContext(
1108
+ var FormFieldContext = React14.createContext(
1107
1109
  {}
1108
1110
  );
1109
1111
  var FormField = ({
@@ -1112,8 +1114,8 @@ var FormField = ({
1112
1114
  return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
1113
1115
  };
1114
1116
  var useFormField = () => {
1115
- const fieldContext = React7.useContext(FormFieldContext);
1116
- const itemContext = React7.useContext(FormItemContext);
1117
+ const fieldContext = React14.useContext(FormFieldContext);
1118
+ const itemContext = React14.useContext(FormItemContext);
1117
1119
  const { getFieldState } = useFormContext();
1118
1120
  const formState = useFormState({ name: fieldContext.name });
1119
1121
  const fieldState = getFieldState(fieldContext.name, formState);
@@ -1130,11 +1132,11 @@ var useFormField = () => {
1130
1132
  ...fieldState
1131
1133
  };
1132
1134
  };
1133
- var FormItemContext = React7.createContext(
1135
+ var FormItemContext = React14.createContext(
1134
1136
  {}
1135
1137
  );
1136
1138
  function FormItem({ className, ...props }) {
1137
- const id = React7.useId();
1139
+ const id = React14.useId();
1138
1140
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx(
1139
1141
  "div",
1140
1142
  {
@@ -1418,7 +1420,7 @@ var cardVariants = cva(
1418
1420
  {
1419
1421
  variants: {
1420
1422
  variant: {
1421
- default: "bg-card border shadow",
1423
+ default: "bg-card border",
1422
1424
  glass: [
1423
1425
  "glass-context",
1424
1426
  // Enables glass semantic token overrides for children
@@ -1673,6 +1675,298 @@ function AvatarFallback({
1673
1675
  }
1674
1676
  );
1675
1677
  }
1678
+ function DropdownMenu({
1679
+ ...props
1680
+ }) {
1681
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1682
+ }
1683
+ function DropdownMenuPortal({
1684
+ ...props
1685
+ }) {
1686
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
1687
+ }
1688
+ function DropdownMenuTrigger({
1689
+ ...props
1690
+ }) {
1691
+ return /* @__PURE__ */ jsx(
1692
+ DropdownMenuPrimitive.Trigger,
1693
+ {
1694
+ "data-slot": "dropdown-menu-trigger",
1695
+ ...props
1696
+ }
1697
+ );
1698
+ }
1699
+ function DropdownMenuContent({
1700
+ className,
1701
+ sideOffset = 4,
1702
+ ...props
1703
+ }) {
1704
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1705
+ DropdownMenuPrimitive.Content,
1706
+ {
1707
+ "data-slot": "dropdown-menu-content",
1708
+ sideOffset,
1709
+ className: cn(
1710
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
1711
+ className
1712
+ ),
1713
+ ...props
1714
+ }
1715
+ ) });
1716
+ }
1717
+ function DropdownMenuGroup({
1718
+ ...props
1719
+ }) {
1720
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
1721
+ }
1722
+ function DropdownMenuItem({
1723
+ className,
1724
+ inset,
1725
+ variant = "default",
1726
+ ...props
1727
+ }) {
1728
+ return /* @__PURE__ */ jsx(
1729
+ DropdownMenuPrimitive.Item,
1730
+ {
1731
+ "data-slot": "dropdown-menu-item",
1732
+ "data-inset": inset,
1733
+ "data-variant": variant,
1734
+ className: cn(
1735
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1736
+ className
1737
+ ),
1738
+ ...props
1739
+ }
1740
+ );
1741
+ }
1742
+ function DropdownMenuCheckboxItem({
1743
+ className,
1744
+ children,
1745
+ checked,
1746
+ ...props
1747
+ }) {
1748
+ return /* @__PURE__ */ jsxs(
1749
+ DropdownMenuPrimitive.CheckboxItem,
1750
+ {
1751
+ "data-slot": "dropdown-menu-checkbox-item",
1752
+ className: cn(
1753
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1754
+ className
1755
+ ),
1756
+ checked,
1757
+ ...props,
1758
+ children: [
1759
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
1760
+ children
1761
+ ]
1762
+ }
1763
+ );
1764
+ }
1765
+ function DropdownMenuRadioGroup({
1766
+ ...props
1767
+ }) {
1768
+ return /* @__PURE__ */ jsx(
1769
+ DropdownMenuPrimitive.RadioGroup,
1770
+ {
1771
+ "data-slot": "dropdown-menu-radio-group",
1772
+ ...props
1773
+ }
1774
+ );
1775
+ }
1776
+ function DropdownMenuRadioItem({
1777
+ className,
1778
+ children,
1779
+ ...props
1780
+ }) {
1781
+ return /* @__PURE__ */ jsxs(
1782
+ DropdownMenuPrimitive.RadioItem,
1783
+ {
1784
+ "data-slot": "dropdown-menu-radio-item",
1785
+ className: cn(
1786
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1787
+ className
1788
+ ),
1789
+ ...props,
1790
+ children: [
1791
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
1792
+ children
1793
+ ]
1794
+ }
1795
+ );
1796
+ }
1797
+ function DropdownMenuLabel({
1798
+ className,
1799
+ inset,
1800
+ ...props
1801
+ }) {
1802
+ return /* @__PURE__ */ jsx(
1803
+ DropdownMenuPrimitive.Label,
1804
+ {
1805
+ "data-slot": "dropdown-menu-label",
1806
+ "data-inset": inset,
1807
+ className: cn(
1808
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
1809
+ className
1810
+ ),
1811
+ ...props
1812
+ }
1813
+ );
1814
+ }
1815
+ function DropdownMenuSeparator({
1816
+ className,
1817
+ ...props
1818
+ }) {
1819
+ return /* @__PURE__ */ jsx(
1820
+ DropdownMenuPrimitive.Separator,
1821
+ {
1822
+ "data-slot": "dropdown-menu-separator",
1823
+ className: cn("bg-border -mx-1 my-1 h-px", className),
1824
+ ...props
1825
+ }
1826
+ );
1827
+ }
1828
+ function DropdownMenuShortcut({
1829
+ className,
1830
+ ...props
1831
+ }) {
1832
+ return /* @__PURE__ */ jsx(
1833
+ "span",
1834
+ {
1835
+ "data-slot": "dropdown-menu-shortcut",
1836
+ className: cn(
1837
+ "text-muted-foreground ml-auto text-xs tracking-widest",
1838
+ className
1839
+ ),
1840
+ ...props
1841
+ }
1842
+ );
1843
+ }
1844
+ function DropdownMenuSub({
1845
+ ...props
1846
+ }) {
1847
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
1848
+ }
1849
+ function DropdownMenuSubTrigger({
1850
+ className,
1851
+ inset,
1852
+ children,
1853
+ ...props
1854
+ }) {
1855
+ return /* @__PURE__ */ jsxs(
1856
+ DropdownMenuPrimitive.SubTrigger,
1857
+ {
1858
+ "data-slot": "dropdown-menu-sub-trigger",
1859
+ "data-inset": inset,
1860
+ className: cn(
1861
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1862
+ className
1863
+ ),
1864
+ ...props,
1865
+ children: [
1866
+ children,
1867
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })
1868
+ ]
1869
+ }
1870
+ );
1871
+ }
1872
+ function DropdownMenuSubContent({
1873
+ className,
1874
+ ...props
1875
+ }) {
1876
+ return /* @__PURE__ */ jsx(
1877
+ DropdownMenuPrimitive.SubContent,
1878
+ {
1879
+ "data-slot": "dropdown-menu-sub-content",
1880
+ className: cn(
1881
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
1882
+ className
1883
+ ),
1884
+ ...props
1885
+ }
1886
+ );
1887
+ }
1888
+ function UserAvatarsDropdown({
1889
+ users,
1890
+ selectedUserId,
1891
+ onSelect,
1892
+ maxVisible = 2,
1893
+ label = "All",
1894
+ className
1895
+ }) {
1896
+ const visibleUsers = users.slice(0, maxVisible);
1897
+ const overflowCount = Math.max(0, users.length - maxVisible);
1898
+ const getInitials = (name) => {
1899
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
1900
+ };
1901
+ const selectedUser = users.find((u) => u.id === selectedUserId);
1902
+ const displayLabel = selectedUserId ? selectedUser?.name || "User" : label;
1903
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1904
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1905
+ "button",
1906
+ {
1907
+ type: "button",
1908
+ className: cn(
1909
+ "flex items-center gap-2 rounded border border-border bg-background px-3 py-1.5 text-sm transition-colors",
1910
+ "hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1911
+ className
1912
+ ),
1913
+ children: [
1914
+ /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
1915
+ visibleUsers.map((user) => /* @__PURE__ */ jsxs(
1916
+ Avatar,
1917
+ {
1918
+ className: "size-6 border-2 border-background",
1919
+ children: [
1920
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }),
1921
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[10px]", children: getInitials(user.name) })
1922
+ ]
1923
+ },
1924
+ user.id
1925
+ )),
1926
+ overflowCount > 0 && /* @__PURE__ */ jsxs("div", { className: "flex size-6 items-center justify-center rounded-full border-2 border-background bg-muted text-[10px] font-medium", children: [
1927
+ "+",
1928
+ overflowCount
1929
+ ] })
1930
+ ] }),
1931
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: displayLabel }),
1932
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 text-muted-foreground" })
1933
+ ]
1934
+ }
1935
+ ) }),
1936
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-48", children: [
1937
+ /* @__PURE__ */ jsxs(
1938
+ DropdownMenuItem,
1939
+ {
1940
+ onClick: () => onSelect(null),
1941
+ className: "flex items-center justify-between",
1942
+ children: [
1943
+ /* @__PURE__ */ jsx("span", { children: "All users" }),
1944
+ selectedUserId === null && /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" })
1945
+ ]
1946
+ }
1947
+ ),
1948
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
1949
+ users.map((user) => /* @__PURE__ */ jsxs(
1950
+ DropdownMenuItem,
1951
+ {
1952
+ onClick: () => onSelect(user.id),
1953
+ className: "flex items-center justify-between",
1954
+ children: [
1955
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1956
+ /* @__PURE__ */ jsxs(Avatar, { className: "size-5", children: [
1957
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }),
1958
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[8px]", children: getInitials(user.name) })
1959
+ ] }),
1960
+ /* @__PURE__ */ jsx("span", { children: user.name })
1961
+ ] }),
1962
+ selectedUserId === user.id && /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" })
1963
+ ]
1964
+ },
1965
+ user.id
1966
+ ))
1967
+ ] })
1968
+ ] });
1969
+ }
1676
1970
  function Skeleton({ className, ...props }) {
1677
1971
  return /* @__PURE__ */ jsx(
1678
1972
  "div",
@@ -1759,7 +2053,7 @@ function TabsList({
1759
2053
  {
1760
2054
  "data-slot": "tabs-list",
1761
2055
  className: cn(
1762
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
2056
+ "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px] dark:bg-[#1a1a1a]",
1763
2057
  className
1764
2058
  ),
1765
2059
  ...props
@@ -1775,7 +2069,7 @@ function TabsTrigger({
1775
2069
  {
1776
2070
  "data-slot": "tabs-trigger",
1777
2071
  className: cn(
1778
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
2072
+ "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-input data-[state=inactive]:hover:bg-accent data-[state=inactive]:hover:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1779
2073
  className
1780
2074
  ),
1781
2075
  ...props
@@ -1944,8 +2238,8 @@ function CalendarDayButton({
1944
2238
  modifiers,
1945
2239
  ...props
1946
2240
  }) {
1947
- const ref = React7.useRef(null);
1948
- React7.useEffect(() => {
2241
+ const ref = React14.useRef(null);
2242
+ React14.useEffect(() => {
1949
2243
  if (modifiers.focused) ref.current?.focus();
1950
2244
  }, [modifiers.focused]);
1951
2245
  return /* @__PURE__ */ jsx(
@@ -1966,9 +2260,9 @@ function CalendarDayButton({
1966
2260
  }
1967
2261
  );
1968
2262
  }
1969
- var CarouselContext = React7.createContext(null);
2263
+ var CarouselContext = React14.createContext(null);
1970
2264
  function useCarousel() {
1971
- const context = React7.useContext(CarouselContext);
2265
+ const context = React14.useContext(CarouselContext);
1972
2266
  if (!context) {
1973
2267
  throw new Error("useCarousel must be used within a <Carousel />");
1974
2268
  }
@@ -1990,20 +2284,20 @@ function Carousel({
1990
2284
  },
1991
2285
  plugins
1992
2286
  );
1993
- const [canScrollPrev, setCanScrollPrev] = React7.useState(false);
1994
- const [canScrollNext, setCanScrollNext] = React7.useState(false);
1995
- const onSelect = React7.useCallback((api2) => {
2287
+ const [canScrollPrev, setCanScrollPrev] = React14.useState(false);
2288
+ const [canScrollNext, setCanScrollNext] = React14.useState(false);
2289
+ const onSelect = React14.useCallback((api2) => {
1996
2290
  if (!api2) return;
1997
2291
  setCanScrollPrev(api2.canScrollPrev());
1998
2292
  setCanScrollNext(api2.canScrollNext());
1999
2293
  }, []);
2000
- const scrollPrev = React7.useCallback(() => {
2294
+ const scrollPrev = React14.useCallback(() => {
2001
2295
  api?.scrollPrev();
2002
2296
  }, [api]);
2003
- const scrollNext = React7.useCallback(() => {
2297
+ const scrollNext = React14.useCallback(() => {
2004
2298
  api?.scrollNext();
2005
2299
  }, [api]);
2006
- const handleKeyDown = React7.useCallback(
2300
+ const handleKeyDown = React14.useCallback(
2007
2301
  (event) => {
2008
2302
  if (event.key === "ArrowLeft") {
2009
2303
  event.preventDefault();
@@ -2015,11 +2309,11 @@ function Carousel({
2015
2309
  },
2016
2310
  [scrollPrev, scrollNext]
2017
2311
  );
2018
- React7.useEffect(() => {
2312
+ React14.useEffect(() => {
2019
2313
  if (!api || !setApi) return;
2020
2314
  setApi(api);
2021
2315
  }, [api, setApi]);
2022
- React7.useEffect(() => {
2316
+ React14.useEffect(() => {
2023
2317
  if (!api) return;
2024
2318
  onSelect(api);
2025
2319
  api.on("reInit", onSelect);
@@ -2152,9 +2446,9 @@ function CarouselNext({
2152
2446
  );
2153
2447
  }
2154
2448
  var THEMES = { light: "", dark: ".dark" };
2155
- var ChartContext = React7.createContext(null);
2449
+ var ChartContext = React14.createContext(null);
2156
2450
  function useChart() {
2157
- const context = React7.useContext(ChartContext);
2451
+ const context = React14.useContext(ChartContext);
2158
2452
  if (!context) {
2159
2453
  throw new Error("useChart must be used within a <ChartContainer />");
2160
2454
  }
@@ -2167,7 +2461,7 @@ function ChartContainer({
2167
2461
  config,
2168
2462
  ...props
2169
2463
  }) {
2170
- const uniqueId = React7.useId();
2464
+ const uniqueId = React14.useId();
2171
2465
  const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
2172
2466
  return /* @__PURE__ */ jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxs(
2173
2467
  "div",
@@ -2228,7 +2522,7 @@ function ChartTooltipContent({
2228
2522
  labelKey
2229
2523
  }) {
2230
2524
  const { config } = useChart();
2231
- const tooltipLabel = React7.useMemo(() => {
2525
+ const tooltipLabel = React14.useMemo(() => {
2232
2526
  if (hideLabel || !payload?.length) {
2233
2527
  return null;
2234
2528
  }
@@ -2522,7 +2816,7 @@ var itemVariants = cva(
2522
2816
  }
2523
2817
  }
2524
2818
  );
2525
- function Item5({
2819
+ function Item6({
2526
2820
  className,
2527
2821
  variant = "default",
2528
2822
  size = "default",
@@ -2930,40 +3224,27 @@ function TooltipContent({
2930
3224
  }
2931
3225
  ) });
2932
3226
  }
2933
- var M = (e, i, s, u, m, a, l, h) => {
2934
- let d = document.documentElement, w = ["light", "dark"];
2935
- function p(n) {
2936
- (Array.isArray(e) ? e : [e]).forEach((y) => {
2937
- let k = y === "class", S = k && a ? m.map((f) => a[f] || f) : m;
2938
- k ? (d.classList.remove(...S), d.classList.add(a && a[n] ? a[n] : n)) : d.setAttribute(y, n);
2939
- }), R(n);
2940
- }
2941
- function R(n) {
2942
- h && w.includes(n) && (d.style.colorScheme = n);
2943
- }
2944
- function c() {
2945
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2946
- }
2947
- if (u) p(u);
2948
- else try {
2949
- let n = localStorage.getItem(i) || s, y = l && n === "system" ? c() : n;
2950
- p(y);
2951
- } catch (n) {
2952
- }
2953
- };
2954
- var x = React7.createContext(void 0);
2955
- var U = { setTheme: (e) => {
2956
- }, themes: [] };
2957
- var z = () => {
2958
- var e;
2959
- return (e = React7.useContext(x)) != null ? e : U;
2960
- };
2961
- React7.memo(({ forcedTheme: e, storageKey: i, attribute: s, enableSystem: u, enableColorScheme: m, defaultTheme: a, value: l, themes: h, nonce: d, scriptProps: w }) => {
2962
- let p = JSON.stringify([s, i, a, e, h, l, u, m]).slice(1, -1);
2963
- return React7.createElement("script", { ...w, suppressHydrationWarning: true, nonce: typeof window == "undefined" ? d : "", dangerouslySetInnerHTML: { __html: `(${M.toString()})(${p})` } });
2964
- });
2965
- var Toaster = ({ ...props }) => {
2966
- const { theme = "system" } = z();
3227
+ function useDetectTheme() {
3228
+ const [theme, setTheme] = React14.useState("light");
3229
+ React14.useEffect(() => {
3230
+ const isDark = document.documentElement.classList.contains("dark");
3231
+ setTheme(isDark ? "dark" : "light");
3232
+ const observer = new MutationObserver((mutations) => {
3233
+ mutations.forEach((mutation) => {
3234
+ if (mutation.attributeName === "class") {
3235
+ const isDark2 = document.documentElement.classList.contains("dark");
3236
+ setTheme(isDark2 ? "dark" : "light");
3237
+ }
3238
+ });
3239
+ });
3240
+ observer.observe(document.documentElement, { attributes: true });
3241
+ return () => observer.disconnect();
3242
+ }, []);
3243
+ return theme;
3244
+ }
3245
+ var Toaster = ({ theme: themeProp, ...props }) => {
3246
+ const detectedTheme = useDetectTheme();
3247
+ const theme = themeProp ?? detectedTheme;
2967
3248
  return /* @__PURE__ */ jsx(
2968
3249
  Toaster$1,
2969
3250
  {
@@ -3466,215 +3747,52 @@ function CommandShortcut({
3466
3747
  }
3467
3748
  );
3468
3749
  }
3469
- function DropdownMenu({
3470
- ...props
3471
- }) {
3472
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
3473
- }
3474
- function DropdownMenuPortal({
3475
- ...props
3476
- }) {
3477
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
3478
- }
3479
- function DropdownMenuTrigger({
3480
- ...props
3481
- }) {
3482
- return /* @__PURE__ */ jsx(
3483
- DropdownMenuPrimitive.Trigger,
3484
- {
3485
- "data-slot": "dropdown-menu-trigger",
3486
- ...props
3487
- }
3488
- );
3489
- }
3490
- function DropdownMenuContent({
3491
- className,
3492
- sideOffset = 4,
3493
- ...props
3494
- }) {
3495
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
3496
- DropdownMenuPrimitive.Content,
3497
- {
3498
- "data-slot": "dropdown-menu-content",
3499
- sideOffset,
3500
- className: cn(
3501
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
3502
- className
3503
- ),
3504
- ...props
3505
- }
3506
- ) });
3507
- }
3508
- function DropdownMenuGroup({
3509
- ...props
3510
- }) {
3511
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
3512
- }
3513
- function DropdownMenuItem({
3514
- className,
3515
- inset,
3516
- variant = "default",
3517
- ...props
3518
- }) {
3519
- return /* @__PURE__ */ jsx(
3520
- DropdownMenuPrimitive.Item,
3521
- {
3522
- "data-slot": "dropdown-menu-item",
3523
- "data-inset": inset,
3524
- "data-variant": variant,
3525
- className: cn(
3526
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
3527
- className
3528
- ),
3529
- ...props
3530
- }
3531
- );
3532
- }
3533
- function DropdownMenuCheckboxItem({
3534
- className,
3535
- children,
3536
- checked,
3537
- ...props
3538
- }) {
3539
- return /* @__PURE__ */ jsxs(
3540
- DropdownMenuPrimitive.CheckboxItem,
3541
- {
3542
- "data-slot": "dropdown-menu-checkbox-item",
3543
- className: cn(
3544
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
3545
- className
3546
- ),
3547
- checked,
3548
- ...props,
3549
- children: [
3550
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
3551
- children
3552
- ]
3553
- }
3554
- );
3555
- }
3556
- function DropdownMenuRadioGroup({
3557
- ...props
3558
- }) {
3559
- return /* @__PURE__ */ jsx(
3560
- DropdownMenuPrimitive.RadioGroup,
3561
- {
3562
- "data-slot": "dropdown-menu-radio-group",
3563
- ...props
3564
- }
3565
- );
3566
- }
3567
- function DropdownMenuRadioItem({
3568
- className,
3569
- children,
3570
- ...props
3571
- }) {
3572
- return /* @__PURE__ */ jsxs(
3573
- DropdownMenuPrimitive.RadioItem,
3574
- {
3575
- "data-slot": "dropdown-menu-radio-item",
3576
- className: cn(
3577
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
3578
- className
3579
- ),
3580
- ...props,
3581
- children: [
3582
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
3583
- children
3584
- ]
3585
- }
3586
- );
3587
- }
3588
- function DropdownMenuLabel({
3589
- className,
3590
- inset,
3591
- ...props
3592
- }) {
3593
- return /* @__PURE__ */ jsx(
3594
- DropdownMenuPrimitive.Label,
3595
- {
3596
- "data-slot": "dropdown-menu-label",
3597
- "data-inset": inset,
3598
- className: cn(
3599
- "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
3600
- className
3601
- ),
3602
- ...props
3603
- }
3604
- );
3605
- }
3606
- function DropdownMenuSeparator({
3607
- className,
3608
- ...props
3609
- }) {
3610
- return /* @__PURE__ */ jsx(
3611
- DropdownMenuPrimitive.Separator,
3612
- {
3613
- "data-slot": "dropdown-menu-separator",
3614
- className: cn("bg-border -mx-1 my-1 h-px", className),
3615
- ...props
3616
- }
3617
- );
3618
- }
3619
- function DropdownMenuShortcut({
3620
- className,
3621
- ...props
3622
- }) {
3623
- return /* @__PURE__ */ jsx(
3624
- "span",
3625
- {
3626
- "data-slot": "dropdown-menu-shortcut",
3627
- className: cn(
3628
- "text-muted-foreground ml-auto text-xs tracking-widest",
3629
- className
3630
- ),
3631
- ...props
3632
- }
3633
- );
3634
- }
3635
- function DropdownMenuSub({
3636
- ...props
3637
- }) {
3638
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
3639
- }
3640
- function DropdownMenuSubTrigger({
3641
- className,
3642
- inset,
3643
- children,
3644
- ...props
3645
- }) {
3646
- return /* @__PURE__ */ jsxs(
3647
- DropdownMenuPrimitive.SubTrigger,
3648
- {
3649
- "data-slot": "dropdown-menu-sub-trigger",
3650
- "data-inset": inset,
3651
- className: cn(
3652
- "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
3653
- className
3654
- ),
3655
- ...props,
3656
- children: [
3657
- children,
3658
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })
3659
- ]
3660
- }
3661
- );
3662
- }
3663
- function DropdownMenuSubContent({
3664
- className,
3665
- ...props
3666
- }) {
3667
- return /* @__PURE__ */ jsx(
3668
- DropdownMenuPrimitive.SubContent,
3669
- {
3670
- "data-slot": "dropdown-menu-sub-content",
3671
- className: cn(
3672
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
3673
- className
3674
- ),
3675
- ...props
3676
- }
3677
- );
3750
+ var SearchTrigger = React14.forwardRef(
3751
+ ({
3752
+ className,
3753
+ placeholder = "Search...",
3754
+ showShortcut = true,
3755
+ shortcutKey = "K",
3756
+ shortcutModifier = "\u2318",
3757
+ ...props
3758
+ }, ref) => {
3759
+ return /* @__PURE__ */ jsxs(
3760
+ Button,
3761
+ {
3762
+ ref,
3763
+ variant: "outline",
3764
+ "data-slot": "search-trigger",
3765
+ className: cn(
3766
+ "relative h-9 w-full justify-start rounded-full bg-background text-sm text-muted-foreground",
3767
+ "sm:w-64 sm:max-w-[280px]",
3768
+ className
3769
+ ),
3770
+ ...props,
3771
+ children: [
3772
+ /* @__PURE__ */ jsx(SearchIcon, { className: "mr-2 h-4 w-4 shrink-0" }),
3773
+ /* @__PURE__ */ jsx("span", { className: "hidden truncate sm:inline-flex", children: placeholder }),
3774
+ /* @__PURE__ */ jsx("span", { className: "truncate sm:hidden", children: "Search" }),
3775
+ showShortcut && /* @__PURE__ */ jsxs(Kbd, { className: "pointer-events-none absolute right-2 hidden h-5 select-none items-center gap-0.5 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium sm:flex", children: [
3776
+ /* @__PURE__ */ jsx("span", { className: "text-xs", children: shortcutModifier }),
3777
+ shortcutKey
3778
+ ] })
3779
+ ]
3780
+ }
3781
+ );
3782
+ }
3783
+ );
3784
+ SearchTrigger.displayName = "SearchTrigger";
3785
+ function useSearchShortcut(onOpen, key = "k") {
3786
+ React14.useEffect(() => {
3787
+ const down = (e) => {
3788
+ if (e.key.toLowerCase() === key.toLowerCase() && (e.metaKey || e.ctrlKey)) {
3789
+ e.preventDefault();
3790
+ onOpen();
3791
+ }
3792
+ };
3793
+ document.addEventListener("keydown", down);
3794
+ return () => document.removeEventListener("keydown", down);
3795
+ }, [onOpen, key]);
3678
3796
  }
3679
3797
  function Menubar({
3680
3798
  className,
@@ -4693,9 +4811,9 @@ var SIDEBAR_WIDTH = "16rem";
4693
4811
  var SIDEBAR_WIDTH_MOBILE = "18rem";
4694
4812
  var SIDEBAR_WIDTH_ICON = "3rem";
4695
4813
  var SIDEBAR_KEYBOARD_SHORTCUT = "b";
4696
- var SidebarContext = React7.createContext(null);
4814
+ var SidebarContext = React14.createContext(null);
4697
4815
  function useSidebar() {
4698
- const context = React7.useContext(SidebarContext);
4816
+ const context = React14.useContext(SidebarContext);
4699
4817
  if (!context) {
4700
4818
  throw new Error("useSidebar must be used within a SidebarProvider.");
4701
4819
  }
@@ -4711,10 +4829,10 @@ function SidebarProvider({
4711
4829
  ...props
4712
4830
  }) {
4713
4831
  const isMobile = useIsMobile();
4714
- const [openMobile, setOpenMobile] = React7.useState(false);
4715
- const [_open, _setOpen] = React7.useState(defaultOpen);
4832
+ const [openMobile, setOpenMobile] = React14.useState(false);
4833
+ const [_open, _setOpen] = React14.useState(defaultOpen);
4716
4834
  const open = openProp ?? _open;
4717
- const setOpen = React7.useCallback(
4835
+ const setOpen = React14.useCallback(
4718
4836
  (value) => {
4719
4837
  const openState = typeof value === "function" ? value(open) : value;
4720
4838
  if (setOpenProp) {
@@ -4726,10 +4844,10 @@ function SidebarProvider({
4726
4844
  },
4727
4845
  [setOpenProp, open]
4728
4846
  );
4729
- const toggleSidebar = React7.useCallback(() => {
4847
+ const toggleSidebar = React14.useCallback(() => {
4730
4848
  return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
4731
4849
  }, [isMobile, setOpen, setOpenMobile]);
4732
- React7.useEffect(() => {
4850
+ React14.useEffect(() => {
4733
4851
  const handleKeyDown = (event) => {
4734
4852
  if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
4735
4853
  event.preventDefault();
@@ -4740,7 +4858,7 @@ function SidebarProvider({
4740
4858
  return () => window.removeEventListener("keydown", handleKeyDown);
4741
4859
  }, [toggleSidebar]);
4742
4860
  const state = open ? "expanded" : "collapsed";
4743
- const contextValue = React7.useMemo(
4861
+ const contextValue = React14.useMemo(
4744
4862
  () => ({
4745
4863
  state,
4746
4864
  open,
@@ -5198,7 +5316,7 @@ function SidebarMenuSkeleton({
5198
5316
  showIcon = false,
5199
5317
  ...props
5200
5318
  }) {
5201
- const width = React7.useMemo(() => {
5319
+ const width = React14.useMemo(() => {
5202
5320
  return `${Math.floor(Math.random() * 40) + 50}%`;
5203
5321
  }, []);
5204
5322
  return /* @__PURE__ */ jsxs(
@@ -5296,8 +5414,7 @@ var sectionVariants = cva(
5296
5414
  default: [
5297
5415
  "bg-[var(--color-bg-surface)]",
5298
5416
  "border border-[var(--color-border-subtle)]",
5299
- "text-[var(--color-text-main)]",
5300
- "shadow-sm"
5417
+ "text-[var(--color-text-main)]"
5301
5418
  ].join(" "),
5302
5419
  // Glass Light - frosted glass for dark or image backgrounds
5303
5420
  "glass-light": [
@@ -5342,7 +5459,7 @@ var sectionVariants = cva(
5342
5459
  }
5343
5460
  );
5344
5461
  var isGlassVariant = (variant) => variant?.startsWith("glass-") ?? false;
5345
- var Section = React7.forwardRef(
5462
+ var Section = React14.forwardRef(
5346
5463
  ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
5347
5464
  "section",
5348
5465
  {
@@ -5354,7 +5471,7 @@ var Section = React7.forwardRef(
5354
5471
  )
5355
5472
  );
5356
5473
  Section.displayName = "Section";
5357
- var SectionHeader = React7.forwardRef(
5474
+ var SectionHeader = React14.forwardRef(
5358
5475
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5359
5476
  "div",
5360
5477
  {
@@ -5369,7 +5486,7 @@ var SectionHeader = React7.forwardRef(
5369
5486
  )
5370
5487
  );
5371
5488
  SectionHeader.displayName = "SectionHeader";
5372
- var SectionTitle = React7.forwardRef(
5489
+ var SectionTitle = React14.forwardRef(
5373
5490
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5374
5491
  "h2",
5375
5492
  {
@@ -5383,7 +5500,7 @@ var SectionTitle = React7.forwardRef(
5383
5500
  )
5384
5501
  );
5385
5502
  SectionTitle.displayName = "SectionTitle";
5386
- var SectionDescription = React7.forwardRef(
5503
+ var SectionDescription = React14.forwardRef(
5387
5504
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5388
5505
  "p",
5389
5506
  {
@@ -5397,7 +5514,7 @@ var SectionDescription = React7.forwardRef(
5397
5514
  )
5398
5515
  );
5399
5516
  SectionDescription.displayName = "SectionDescription";
5400
- var SectionContent = React7.forwardRef(
5517
+ var SectionContent = React14.forwardRef(
5401
5518
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5402
5519
  "div",
5403
5520
  {
@@ -5411,7 +5528,7 @@ var SectionContent = React7.forwardRef(
5411
5528
  )
5412
5529
  );
5413
5530
  SectionContent.displayName = "SectionContent";
5414
- var SectionFooter = React7.forwardRef(
5531
+ var SectionFooter = React14.forwardRef(
5415
5532
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5416
5533
  "div",
5417
5534
  {
@@ -5427,7 +5544,3182 @@ var SectionFooter = React7.forwardRef(
5427
5544
  )
5428
5545
  );
5429
5546
  SectionFooter.displayName = "SectionFooter";
5547
+ function SearchForm({ ...props }) {
5548
+ return /* @__PURE__ */ jsx("form", { ...props, children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
5549
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "search", className: "sr-only", children: "Search" }),
5550
+ /* @__PURE__ */ jsx(
5551
+ SidebarInput,
5552
+ {
5553
+ id: "search",
5554
+ placeholder: "Type to search...",
5555
+ className: "h-8 pl-7"
5556
+ }
5557
+ ),
5558
+ /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 opacity-50 select-none" })
5559
+ ] }) });
5560
+ }
5561
+ function SiteHeader({
5562
+ trigger,
5563
+ breadcrumbs = [
5564
+ { label: "Building Your Application", href: "#" },
5565
+ { label: "Data Fetching" }
5566
+ ],
5567
+ showSearch = true,
5568
+ className,
5569
+ children
5570
+ }) {
5571
+ return /* @__PURE__ */ jsx(
5572
+ "header",
5573
+ {
5574
+ "data-slot": "site-header",
5575
+ className: cn(
5576
+ "bg-sidebar text-sidebar-foreground sticky top-0 z-50 flex w-full items-center border-b border-sidebar-border",
5577
+ className
5578
+ ),
5579
+ children: /* @__PURE__ */ jsxs("div", { className: "flex h-[var(--header-height,3.5rem)] w-full items-center gap-[var(--j3m-spacing-s)] px-[var(--j3m-spacing-m)]", children: [
5580
+ trigger,
5581
+ trigger && /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
5582
+ /* @__PURE__ */ jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxs(React14.Fragment, { children: [
5583
+ index > 0 && /* @__PURE__ */ jsx(BreadcrumbSeparator, {}),
5584
+ /* @__PURE__ */ jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) })
5585
+ ] }, index)) }) }),
5586
+ showSearch && /* @__PURE__ */ jsx(SearchForm, { className: "w-full sm:ml-auto sm:w-auto" }),
5587
+ children
5588
+ ] })
5589
+ }
5590
+ );
5591
+ }
5592
+ function NavMain({ items, label = "Platform" }) {
5593
+ return /* @__PURE__ */ jsxs(SidebarGroup, { children: [
5594
+ /* @__PURE__ */ jsx(SidebarGroupLabel, { children: label }),
5595
+ /* @__PURE__ */ jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsx(Collapsible, { asChild: true, defaultOpen: item.isActive, children: /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
5596
+ /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, tooltip: item.title, children: /* @__PURE__ */ jsxs("a", { href: item.url, children: [
5597
+ item.icon && /* @__PURE__ */ jsx(item.icon, {}),
5598
+ /* @__PURE__ */ jsx("span", { children: item.title })
5599
+ ] }) }),
5600
+ item.items?.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
5601
+ /* @__PURE__ */ jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs(SidebarMenuAction, { className: "data-[state=open]:rotate-90", children: [
5602
+ /* @__PURE__ */ jsx(ChevronRightIcon, {}),
5603
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Toggle" })
5604
+ ] }) }),
5605
+ /* @__PURE__ */ jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsx(SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsx("a", { href: subItem.url, children: /* @__PURE__ */ jsx("span", { children: subItem.title }) }) }) }, subItem.title)) }) })
5606
+ ] }) : null
5607
+ ] }) }, item.title)) })
5608
+ ] });
5609
+ }
5610
+ function NavProjects({ projects, label = "Projects" }) {
5611
+ return /* @__PURE__ */ jsxs(SidebarGroup, { className: "group-data-[collapsible=icon]:hidden", children: [
5612
+ /* @__PURE__ */ jsx(SidebarGroupLabel, { children: label }),
5613
+ /* @__PURE__ */ jsxs(SidebarMenu, { children: [
5614
+ projects.map((item) => /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
5615
+ /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, children: /* @__PURE__ */ jsxs("a", { href: item.url, children: [
5616
+ /* @__PURE__ */ jsx(item.icon, {}),
5617
+ /* @__PURE__ */ jsx("span", { children: item.name })
5618
+ ] }) }),
5619
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
5620
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(SidebarMenuAction, { showOnHover: true, children: [
5621
+ /* @__PURE__ */ jsx(MoreHorizontalIcon, {}),
5622
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "More" })
5623
+ ] }) }),
5624
+ /* @__PURE__ */ jsxs(
5625
+ DropdownMenuContent,
5626
+ {
5627
+ className: "w-48 rounded-[var(--j3m-radius-m)]",
5628
+ side: "right",
5629
+ align: "start",
5630
+ sideOffset: 8,
5631
+ children: [
5632
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5633
+ /* @__PURE__ */ jsx(FolderIcon, { className: "text-muted-foreground" }),
5634
+ /* @__PURE__ */ jsx("span", { children: "View Project" })
5635
+ ] }),
5636
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5637
+ /* @__PURE__ */ jsx(ShareIcon, { className: "text-muted-foreground" }),
5638
+ /* @__PURE__ */ jsx("span", { children: "Share Project" })
5639
+ ] }),
5640
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5641
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5642
+ /* @__PURE__ */ jsx(TrashIcon, { className: "text-muted-foreground" }),
5643
+ /* @__PURE__ */ jsx("span", { children: "Delete Project" })
5644
+ ] })
5645
+ ]
5646
+ }
5647
+ )
5648
+ ] })
5649
+ ] }, item.name)),
5650
+ /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, { className: "text-sidebar-foreground/70", children: [
5651
+ /* @__PURE__ */ jsx(MoreHorizontalIcon, { className: "text-sidebar-foreground/70" }),
5652
+ /* @__PURE__ */ jsx("span", { children: "More" })
5653
+ ] }) })
5654
+ ] })
5655
+ ] });
5656
+ }
5657
+ function NavSecondary({ items, ...props }) {
5658
+ return /* @__PURE__ */ jsx(SidebarGroup, { ...props, children: /* @__PURE__ */ jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, size: "sm", children: /* @__PURE__ */ jsxs("a", { href: item.url, children: [
5659
+ /* @__PURE__ */ jsx(item.icon, {}),
5660
+ /* @__PURE__ */ jsx("span", { children: item.title })
5661
+ ] }) }) }, item.title)) }) }) });
5662
+ }
5663
+ function NavUser({ user }) {
5664
+ return /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
5665
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
5666
+ SidebarMenuButton,
5667
+ {
5668
+ size: "lg",
5669
+ className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
5670
+ children: [
5671
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
5672
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
5673
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
5674
+ ] }),
5675
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
5676
+ /* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: user.name }),
5677
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: user.email })
5678
+ ] }),
5679
+ /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "ml-auto size-4" })
5680
+ ]
5681
+ }
5682
+ ) }),
5683
+ /* @__PURE__ */ jsxs(
5684
+ DropdownMenuContent,
5685
+ {
5686
+ className: "w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-[var(--j3m-radius-m)]",
5687
+ side: "right",
5688
+ align: "end",
5689
+ sideOffset: 8,
5690
+ children: [
5691
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm", children: [
5692
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
5693
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
5694
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
5695
+ ] }),
5696
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
5697
+ /* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: user.name }),
5698
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: user.email })
5699
+ ] })
5700
+ ] }) }),
5701
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5702
+ /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5703
+ /* @__PURE__ */ jsx(SparklesIcon, {}),
5704
+ "Upgrade to Pro"
5705
+ ] }) }),
5706
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5707
+ /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
5708
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5709
+ /* @__PURE__ */ jsx(BadgeCheckIcon, {}),
5710
+ "Account"
5711
+ ] }),
5712
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5713
+ /* @__PURE__ */ jsx(CreditCardIcon, {}),
5714
+ "Billing"
5715
+ ] }),
5716
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5717
+ /* @__PURE__ */ jsx(BellIcon, {}),
5718
+ "Notifications"
5719
+ ] })
5720
+ ] }),
5721
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5722
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5723
+ /* @__PURE__ */ jsx(LogOutIcon, {}),
5724
+ "Log out"
5725
+ ] })
5726
+ ]
5727
+ }
5728
+ )
5729
+ ] }) }) });
5730
+ }
5731
+
5732
+ // src/components/event-calendar/types.ts
5733
+ var DEFAULT_WORKING_HOURS = {
5734
+ 0: { from: 0, to: 0 },
5735
+ // Sunday - closed
5736
+ 1: { from: 9, to: 17 },
5737
+ // Monday
5738
+ 2: { from: 9, to: 17 },
5739
+ // Tuesday
5740
+ 3: { from: 9, to: 17 },
5741
+ // Wednesday
5742
+ 4: { from: 9, to: 17 },
5743
+ // Thursday
5744
+ 5: { from: 9, to: 17 },
5745
+ // Friday
5746
+ 6: { from: 0, to: 0 }
5747
+ // Saturday - closed
5748
+ };
5749
+ var DEFAULT_VISIBLE_HOURS = { from: 0, to: 24 };
5750
+ var EVENT_COLORS = {
5751
+ blue: {
5752
+ bg: "bg-blue-500/20",
5753
+ text: "text-blue-700 dark:text-blue-300",
5754
+ border: "border-blue-500"
5755
+ },
5756
+ green: {
5757
+ bg: "bg-green-500/20",
5758
+ text: "text-green-700 dark:text-green-300",
5759
+ border: "border-green-500"
5760
+ },
5761
+ red: {
5762
+ bg: "bg-red-500/20",
5763
+ text: "text-red-700 dark:text-red-300",
5764
+ border: "border-red-500"
5765
+ },
5766
+ yellow: {
5767
+ bg: "bg-yellow-500/20",
5768
+ text: "text-yellow-700 dark:text-yellow-300",
5769
+ border: "border-yellow-500"
5770
+ },
5771
+ purple: {
5772
+ bg: "bg-purple-500/20",
5773
+ text: "text-purple-700 dark:text-purple-300",
5774
+ border: "border-purple-500"
5775
+ },
5776
+ orange: {
5777
+ bg: "bg-primary/20",
5778
+ text: "text-primary dark:text-orange-300",
5779
+ border: "border-primary"
5780
+ }
5781
+ };
5782
+ var VIEW_LABELS = {
5783
+ month: "Month",
5784
+ week: "Week",
5785
+ day: "Day",
5786
+ year: "Year",
5787
+ agenda: "Agenda"
5788
+ };
5789
+ var BADGE_VARIANT_LABELS = {
5790
+ dot: "Dot",
5791
+ colored: "Colored",
5792
+ mixed: "Mixed"
5793
+ };
5794
+ var CalendarContext = React14.createContext(null);
5795
+ function EventCalendarProvider({
5796
+ children,
5797
+ events: initialEvents = [],
5798
+ users: initialUsers = [],
5799
+ defaultDate = /* @__PURE__ */ new Date(),
5800
+ defaultView = "month",
5801
+ defaultBadgeVariant = "colored",
5802
+ defaultUserId = null,
5803
+ defaultWorkingHours = DEFAULT_WORKING_HOURS,
5804
+ defaultVisibleHours = DEFAULT_VISIBLE_HOURS,
5805
+ onEventAdd,
5806
+ onEventUpdate,
5807
+ onEventDelete
5808
+ }) {
5809
+ const [selectedDate, setSelectedDate] = React14.useState(defaultDate);
5810
+ const [selectedUserId, setSelectedUserId] = React14.useState(defaultUserId);
5811
+ const [events, setEventsState] = React14.useState(initialEvents);
5812
+ const [users] = React14.useState(initialUsers);
5813
+ const [badgeVariant, setBadgeVariant] = React14.useState(defaultBadgeVariant);
5814
+ const [view, setView] = React14.useState(defaultView);
5815
+ const [workingHours, setWorkingHours] = React14.useState(defaultWorkingHours);
5816
+ const [visibleHours, setVisibleHours] = React14.useState(defaultVisibleHours);
5817
+ React14.useEffect(() => {
5818
+ setEventsState(initialEvents);
5819
+ }, [initialEvents]);
5820
+ const setEvents = React14.useCallback((newEvents) => {
5821
+ setEventsState(newEvents);
5822
+ }, []);
5823
+ const addEvent = React14.useCallback((event) => {
5824
+ setEventsState((prev) => [...prev, event]);
5825
+ onEventAdd?.(event);
5826
+ }, [onEventAdd]);
5827
+ const updateEvent = React14.useCallback((event) => {
5828
+ setEventsState(
5829
+ (prev) => prev.map((e) => e.id === event.id ? event : e)
5830
+ );
5831
+ onEventUpdate?.(event);
5832
+ }, [onEventUpdate]);
5833
+ const deleteEvent = React14.useCallback((eventId) => {
5834
+ setEventsState((prev) => prev.filter((e) => e.id !== eventId));
5835
+ onEventDelete?.(eventId);
5836
+ }, [onEventDelete]);
5837
+ const goToToday = React14.useCallback(() => {
5838
+ setSelectedDate(/* @__PURE__ */ new Date());
5839
+ }, []);
5840
+ const goToPrevious = React14.useCallback(() => {
5841
+ setSelectedDate((current) => {
5842
+ switch (view) {
5843
+ case "day":
5844
+ return subDays(current, 1);
5845
+ case "week":
5846
+ return subWeeks(current, 1);
5847
+ case "month":
5848
+ return subMonths(current, 1);
5849
+ case "year":
5850
+ return subYears(current, 1);
5851
+ case "agenda":
5852
+ return subMonths(current, 1);
5853
+ default:
5854
+ return current;
5855
+ }
5856
+ });
5857
+ }, [view]);
5858
+ const goToNext = React14.useCallback(() => {
5859
+ setSelectedDate((current) => {
5860
+ switch (view) {
5861
+ case "day":
5862
+ return addDays(current, 1);
5863
+ case "week":
5864
+ return addWeeks(current, 1);
5865
+ case "month":
5866
+ return addMonths(current, 1);
5867
+ case "year":
5868
+ return addYears(current, 1);
5869
+ case "agenda":
5870
+ return addMonths(current, 1);
5871
+ default:
5872
+ return current;
5873
+ }
5874
+ });
5875
+ }, [view]);
5876
+ const contextValue = React14.useMemo(
5877
+ () => ({
5878
+ // State
5879
+ selectedDate,
5880
+ selectedUserId,
5881
+ events,
5882
+ users,
5883
+ badgeVariant,
5884
+ view,
5885
+ workingHours,
5886
+ visibleHours,
5887
+ // Actions
5888
+ setSelectedDate,
5889
+ setSelectedUserId,
5890
+ setEvents,
5891
+ addEvent,
5892
+ updateEvent,
5893
+ deleteEvent,
5894
+ setBadgeVariant,
5895
+ setView,
5896
+ setWorkingHours,
5897
+ setVisibleHours,
5898
+ goToToday,
5899
+ goToPrevious,
5900
+ goToNext
5901
+ }),
5902
+ [
5903
+ selectedDate,
5904
+ selectedUserId,
5905
+ events,
5906
+ users,
5907
+ badgeVariant,
5908
+ view,
5909
+ workingHours,
5910
+ visibleHours,
5911
+ setEvents,
5912
+ addEvent,
5913
+ updateEvent,
5914
+ deleteEvent,
5915
+ goToToday,
5916
+ goToPrevious,
5917
+ goToNext
5918
+ ]
5919
+ );
5920
+ return /* @__PURE__ */ jsx(CalendarContext.Provider, { value: contextValue, children });
5921
+ }
5922
+ function useEventCalendar() {
5923
+ const context = React14.useContext(CalendarContext);
5924
+ if (!context) {
5925
+ throw new Error("useEventCalendar must be used within an EventCalendarProvider");
5926
+ }
5927
+ return context;
5928
+ }
5929
+ function useFilteredEvents() {
5930
+ const { events, selectedUserId } = useEventCalendar();
5931
+ return React14.useMemo(() => {
5932
+ if (!selectedUserId) return events;
5933
+ return events.filter((event) => event.user.id === selectedUserId);
5934
+ }, [events, selectedUserId]);
5935
+ }
5936
+ function useEventsInRange(startDate, endDate) {
5937
+ const filteredEvents = useFilteredEvents();
5938
+ return React14.useMemo(() => {
5939
+ return filteredEvents.filter((event) => {
5940
+ const eventStart = new Date(event.startDate);
5941
+ const eventEnd = new Date(event.endDate);
5942
+ return eventStart <= endDate && eventEnd >= startDate;
5943
+ });
5944
+ }, [filteredEvents, startDate, endDate]);
5945
+ }
5946
+ function rangeText(view, date) {
5947
+ const formatString = "MMM d, yyyy";
5948
+ let start;
5949
+ let end;
5950
+ switch (view) {
5951
+ case "agenda":
5952
+ start = startOfMonth(date);
5953
+ end = endOfMonth(date);
5954
+ break;
5955
+ case "year":
5956
+ start = startOfYear(date);
5957
+ end = endOfYear(date);
5958
+ break;
5959
+ case "month":
5960
+ start = startOfMonth(date);
5961
+ end = endOfMonth(date);
5962
+ break;
5963
+ case "week":
5964
+ start = startOfWeek(date);
5965
+ end = endOfWeek(date);
5966
+ break;
5967
+ case "day":
5968
+ return format(date, formatString);
5969
+ default:
5970
+ return "Error while formatting";
5971
+ }
5972
+ return `${format(start, formatString)} - ${format(end, formatString)}`;
5973
+ }
5974
+ function navigateDate(date, view, direction) {
5975
+ const operations = {
5976
+ agenda: direction === "next" ? addMonths : subMonths,
5977
+ year: direction === "next" ? addYears : subYears,
5978
+ month: direction === "next" ? addMonths : subMonths,
5979
+ week: direction === "next" ? addWeeks : subWeeks,
5980
+ day: direction === "next" ? addDays : subDays
5981
+ };
5982
+ return operations[view](date, 1);
5983
+ }
5984
+ function getEventsCount(events, date, view) {
5985
+ const compareFns = {
5986
+ agenda: isSameMonth,
5987
+ year: isSameYear,
5988
+ day: isSameDay,
5989
+ week: isSameWeek,
5990
+ month: isSameMonth
5991
+ };
5992
+ return events.filter(
5993
+ (event) => compareFns[view](new Date(event.startDate), date)
5994
+ ).length;
5995
+ }
5996
+ function getCurrentEvents(events) {
5997
+ const now = /* @__PURE__ */ new Date();
5998
+ return events.filter(
5999
+ (event) => isWithinInterval(now, {
6000
+ start: parseISO(event.startDate),
6001
+ end: parseISO(event.endDate)
6002
+ })
6003
+ ) || [];
6004
+ }
6005
+ function groupEvents(dayEvents) {
6006
+ const sortedEvents = dayEvents.sort(
6007
+ (a, b) => parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime()
6008
+ );
6009
+ const groups = [];
6010
+ for (const event of sortedEvents) {
6011
+ const eventStart = parseISO(event.startDate);
6012
+ let placed = false;
6013
+ for (const group of groups) {
6014
+ const lastEventInGroup = group[group.length - 1];
6015
+ const lastEventEnd = parseISO(lastEventInGroup.endDate);
6016
+ if (eventStart >= lastEventEnd) {
6017
+ group.push(event);
6018
+ placed = true;
6019
+ break;
6020
+ }
6021
+ }
6022
+ if (!placed) groups.push([event]);
6023
+ }
6024
+ return groups;
6025
+ }
6026
+ function getEventBlockStyle(event, day, groupIndex, groupSize, visibleHoursRange, hourHeight = 96) {
6027
+ const startDate = parseISO(event.startDate);
6028
+ const endDate = parseISO(event.endDate);
6029
+ const dayStart = new Date(day);
6030
+ dayStart.setHours(0, 0, 0, 0);
6031
+ const eventStart = startDate < dayStart ? dayStart : startDate;
6032
+ const startMinutes = differenceInMinutes(eventStart, dayStart);
6033
+ const durationMinutes = differenceInMinutes(endDate, eventStart);
6034
+ const visibleStartMinutes = (visibleHoursRange?.from ?? 0) * 60;
6035
+ const topMinutes = startMinutes - visibleStartMinutes;
6036
+ const topPx = topMinutes / 60 * hourHeight;
6037
+ const heightPx = Math.max(durationMinutes / 60 * hourHeight, hourHeight / 4);
6038
+ const width = 100 / groupSize;
6039
+ const left = groupIndex * width;
6040
+ return {
6041
+ top: `${topPx}px`,
6042
+ height: `${heightPx}px`,
6043
+ width: `${width}%`,
6044
+ left: `${left}%`
6045
+ };
6046
+ }
6047
+ function isWorkingHour(day, hour, workingHours) {
6048
+ const dayIndex = day.getDay();
6049
+ const dayHours = workingHours[dayIndex];
6050
+ return hour >= dayHours.from && hour < dayHours.to;
6051
+ }
6052
+ function getVisibleHours(visibleHours, singleDayEvents) {
6053
+ let earliestEventHour = visibleHours.from;
6054
+ let latestEventHour = visibleHours.to;
6055
+ singleDayEvents.forEach((event) => {
6056
+ const startHour = parseISO(event.startDate).getHours();
6057
+ const endTime = parseISO(event.endDate);
6058
+ const endHour = endTime.getHours() + (endTime.getMinutes() > 0 ? 1 : 0);
6059
+ if (startHour < earliestEventHour) earliestEventHour = startHour;
6060
+ if (endHour > latestEventHour) latestEventHour = endHour;
6061
+ });
6062
+ latestEventHour = Math.min(latestEventHour, 24);
6063
+ const hours = Array.from(
6064
+ { length: latestEventHour - earliestEventHour },
6065
+ (_, i) => i + earliestEventHour
6066
+ );
6067
+ return { hours, earliestEventHour, latestEventHour };
6068
+ }
6069
+ function getCalendarCells(selectedDate) {
6070
+ const currentYear = selectedDate.getFullYear();
6071
+ const currentMonth = selectedDate.getMonth();
6072
+ const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
6073
+ const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay();
6074
+ const daysInMonth = getDaysInMonth(currentYear, currentMonth);
6075
+ const firstDayOfMonth = getFirstDayOfMonth(currentYear, currentMonth);
6076
+ const daysInPrevMonth = getDaysInMonth(currentYear, currentMonth - 1);
6077
+ const totalDays = firstDayOfMonth + daysInMonth;
6078
+ const prevMonthCells = Array.from({ length: firstDayOfMonth }, (_, i) => ({
6079
+ day: daysInPrevMonth - firstDayOfMonth + i + 1,
6080
+ currentMonth: false,
6081
+ date: new Date(
6082
+ currentYear,
6083
+ currentMonth - 1,
6084
+ daysInPrevMonth - firstDayOfMonth + i + 1
6085
+ )
6086
+ }));
6087
+ const currentMonthCells = Array.from({ length: daysInMonth }, (_, i) => ({
6088
+ day: i + 1,
6089
+ currentMonth: true,
6090
+ date: new Date(currentYear, currentMonth, i + 1)
6091
+ }));
6092
+ const nextMonthCells = Array.from(
6093
+ { length: (7 - totalDays % 7) % 7 },
6094
+ (_, i) => ({
6095
+ day: i + 1,
6096
+ currentMonth: false,
6097
+ date: new Date(currentYear, currentMonth + 1, i + 1)
6098
+ })
6099
+ );
6100
+ return [...prevMonthCells, ...currentMonthCells, ...nextMonthCells];
6101
+ }
6102
+ function calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate) {
6103
+ const monthStart = startOfMonth(selectedDate);
6104
+ const monthEnd = endOfMonth(selectedDate);
6105
+ const eventPositions = {};
6106
+ const occupiedPositions = {};
6107
+ eachDayOfInterval({ start: monthStart, end: monthEnd }).forEach((day) => {
6108
+ occupiedPositions[day.toISOString()] = [false, false, false];
6109
+ });
6110
+ const sortedEvents = [
6111
+ ...multiDayEvents.sort((a, b) => {
6112
+ const aDuration = differenceInDays(
6113
+ parseISO(a.endDate),
6114
+ parseISO(a.startDate)
6115
+ );
6116
+ const bDuration = differenceInDays(
6117
+ parseISO(b.endDate),
6118
+ parseISO(b.startDate)
6119
+ );
6120
+ return bDuration - aDuration || parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime();
6121
+ }),
6122
+ ...singleDayEvents.sort(
6123
+ (a, b) => parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime()
6124
+ )
6125
+ ];
6126
+ sortedEvents.forEach((event) => {
6127
+ const eventStart = parseISO(event.startDate);
6128
+ const eventEnd = parseISO(event.endDate);
6129
+ const eventDays = eachDayOfInterval({
6130
+ start: eventStart < monthStart ? monthStart : eventStart,
6131
+ end: eventEnd > monthEnd ? monthEnd : eventEnd
6132
+ });
6133
+ let position = -1;
6134
+ for (let i = 0; i < 3; i++) {
6135
+ if (eventDays.every((day) => {
6136
+ const dayPositions = occupiedPositions[startOfDay(day).toISOString()];
6137
+ return dayPositions && !dayPositions[i];
6138
+ })) {
6139
+ position = i;
6140
+ break;
6141
+ }
6142
+ }
6143
+ if (position !== -1) {
6144
+ eventDays.forEach((day) => {
6145
+ const dayKey = startOfDay(day).toISOString();
6146
+ occupiedPositions[dayKey][position] = true;
6147
+ });
6148
+ eventPositions[event.id] = position;
6149
+ }
6150
+ });
6151
+ return eventPositions;
6152
+ }
6153
+ function getMonthCellEvents(date, events, eventPositions) {
6154
+ const eventsForDate = events.filter((event) => {
6155
+ const eventStart = parseISO(event.startDate);
6156
+ const eventEnd = parseISO(event.endDate);
6157
+ return date >= eventStart && date <= eventEnd || isSameDay(date, eventStart) || isSameDay(date, eventEnd);
6158
+ });
6159
+ return eventsForDate.map((event) => ({
6160
+ ...event,
6161
+ position: eventPositions[event.id] ?? -1,
6162
+ isMultiDay: event.startDate !== event.endDate
6163
+ })).sort((a, b) => {
6164
+ if (a.isMultiDay && !b.isMultiDay) return -1;
6165
+ if (!a.isMultiDay && b.isMultiDay) return 1;
6166
+ return a.position - b.position;
6167
+ });
6168
+ }
6169
+ function getMonthDays(date, weekStartsOn = 0) {
6170
+ const start = startOfWeek(startOfMonth(date), { weekStartsOn });
6171
+ const end = endOfWeek(endOfMonth(date), { weekStartsOn });
6172
+ return eachDayOfInterval({ start, end });
6173
+ }
6174
+ function getWeekDays(date, weekStartsOn = 0) {
6175
+ const start = startOfWeek(date, { weekStartsOn });
6176
+ const end = endOfWeek(date, { weekStartsOn });
6177
+ return eachDayOfInterval({ start, end });
6178
+ }
6179
+ function getDayHours(date, start = 0, end = 24) {
6180
+ const dayStart = setMinutes(setHours(date, start), 0);
6181
+ const dayEnd = setMinutes(setHours(date, end - 1), 59);
6182
+ return eachHourOfInterval({ start: dayStart, end: dayEnd });
6183
+ }
6184
+ function getYearMonths(date) {
6185
+ const start = startOfYear(date);
6186
+ const months = [];
6187
+ for (let i = 0; i < 12; i++) {
6188
+ months.push(new Date(start.getFullYear(), i, 1));
6189
+ }
6190
+ return months;
6191
+ }
6192
+ function getEventsForDate(events, date) {
6193
+ return events.filter((event) => {
6194
+ const eventStart = parseISO(event.startDate);
6195
+ const eventEnd = parseISO(event.endDate);
6196
+ return isWithinInterval(date, {
6197
+ start: startOfDay(eventStart),
6198
+ end: endOfDay(eventEnd)
6199
+ }) || isSameDay(eventStart, date) || isSameDay(eventEnd, date);
6200
+ });
6201
+ }
6202
+ function getEventsInRange(events, start, end) {
6203
+ return events.filter((event) => {
6204
+ const eventStart = parseISO(event.startDate);
6205
+ const eventEnd = parseISO(event.endDate);
6206
+ return eventStart >= start && eventStart <= end || eventEnd >= start && eventEnd <= end || eventStart <= start && eventEnd >= end;
6207
+ });
6208
+ }
6209
+ function splitEventsByDuration(events) {
6210
+ const singleDayEvents = [];
6211
+ const multiDayEvents = [];
6212
+ events.forEach((event) => {
6213
+ const start = parseISO(event.startDate);
6214
+ const end = parseISO(event.endDate);
6215
+ if (isSameDay(start, end)) {
6216
+ singleDayEvents.push(event);
6217
+ } else {
6218
+ multiDayEvents.push(event);
6219
+ }
6220
+ });
6221
+ return { singleDayEvents, multiDayEvents };
6222
+ }
6223
+ function isMultiDayEvent(event) {
6224
+ const start = parseISO(event.startDate);
6225
+ const end = parseISO(event.endDate);
6226
+ return !isSameDay(start, end);
6227
+ }
6228
+ function getEventDuration(event) {
6229
+ const start = parseISO(event.startDate);
6230
+ const end = parseISO(event.endDate);
6231
+ return differenceInDays(end, start) + 1;
6232
+ }
6233
+ function getEventDurationMinutes(event) {
6234
+ const start = parseISO(event.startDate);
6235
+ const end = parseISO(event.endDate);
6236
+ return differenceInMinutes(end, start);
6237
+ }
6238
+ function sortEvents(events) {
6239
+ return [...events].sort((a, b) => {
6240
+ const startDiff = parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime();
6241
+ if (startDiff !== 0) return startDiff;
6242
+ return getEventDuration(b) - getEventDuration(a);
6243
+ });
6244
+ }
6245
+ function getTimePosition(event, visibleHoursRange) {
6246
+ const start = parseISO(event.startDate);
6247
+ const hours = getHours(start);
6248
+ const minutes = getMinutes(start);
6249
+ const startHour = visibleHoursRange?.from ?? 0;
6250
+ const totalMinutes = (hours - startHour) * 60 + minutes;
6251
+ const totalDayMinutes = ((visibleHoursRange?.to ?? 24) - startHour) * 60;
6252
+ return totalMinutes / totalDayMinutes * 100;
6253
+ }
6254
+ function getTimeHeight(event, visibleHoursRange) {
6255
+ const duration = getEventDurationMinutes(event);
6256
+ const totalDayMinutes = ((visibleHoursRange?.to ?? 24) - (visibleHoursRange?.from ?? 0)) * 60;
6257
+ return Math.min(duration / totalDayMinutes * 100, 100);
6258
+ }
6259
+ function formatTime(date, use24h = false) {
6260
+ return format(date, use24h ? "HH:mm" : "h:mm a");
6261
+ }
6262
+ function getWeekDayNames(weekStartsOn = 0, shortNames = true) {
6263
+ const days = [
6264
+ "Sunday",
6265
+ "Monday",
6266
+ "Tuesday",
6267
+ "Wednesday",
6268
+ "Thursday",
6269
+ "Friday",
6270
+ "Saturday"
6271
+ ];
6272
+ const rotated = [...days.slice(weekStartsOn), ...days.slice(0, weekStartsOn)];
6273
+ return shortNames ? rotated.map((d) => d.slice(0, 3)) : rotated;
6274
+ }
6275
+ function getHeaderLabel(date, view) {
6276
+ switch (view) {
6277
+ case "day":
6278
+ return format(date, "EEEE, MMMM d, yyyy");
6279
+ case "week":
6280
+ const weekStart = startOfWeek(date);
6281
+ const weekEnd = endOfWeek(date);
6282
+ if (weekStart.getMonth() === weekEnd.getMonth()) {
6283
+ return format(weekStart, "MMMM d") + " - " + format(weekEnd, "d, yyyy");
6284
+ }
6285
+ return format(weekStart, "MMM d") + " - " + format(weekEnd, "MMM d, yyyy");
6286
+ case "month":
6287
+ return format(date, "MMMM yyyy");
6288
+ case "year":
6289
+ return format(date, "yyyy");
6290
+ case "agenda":
6291
+ return format(date, "MMMM yyyy");
6292
+ default:
6293
+ return format(date, "MMMM yyyy");
6294
+ }
6295
+ }
6296
+ function getViewDateRange(date, view) {
6297
+ switch (view) {
6298
+ case "day":
6299
+ return { start: startOfDay(date), end: endOfDay(date) };
6300
+ case "week":
6301
+ return { start: startOfWeek(date), end: endOfWeek(date) };
6302
+ case "month":
6303
+ return { start: startOfMonth(date), end: endOfMonth(date) };
6304
+ case "year":
6305
+ return { start: startOfYear(date), end: endOfYear(date) };
6306
+ case "agenda":
6307
+ return { start: startOfMonth(date), end: endOfMonth(date) };
6308
+ default:
6309
+ return { start: startOfMonth(date), end: endOfMonth(date) };
6310
+ }
6311
+ }
6312
+ function formatDateRange(start, end) {
6313
+ if (isSameDay(start, end)) {
6314
+ return format(start, "MMM d, yyyy");
6315
+ }
6316
+ if (start.getFullYear() === end.getFullYear()) {
6317
+ if (start.getMonth() === end.getMonth()) {
6318
+ return format(start, "MMM d") + " - " + format(end, "d, yyyy");
6319
+ }
6320
+ return format(start, "MMM d") + " - " + format(end, "MMM d, yyyy");
6321
+ }
6322
+ return format(start, "MMM d, yyyy") + " - " + format(end, "MMM d, yyyy");
6323
+ }
6324
+ function createDefaultEvent(startDate, duration = 60) {
6325
+ return {
6326
+ title: "",
6327
+ description: "",
6328
+ startDate: startDate.toISOString(),
6329
+ endDate: addMinutes(startDate, duration).toISOString(),
6330
+ color: "blue",
6331
+ user: {
6332
+ id: "",
6333
+ name: ""
6334
+ }
6335
+ };
6336
+ }
6337
+ function generateEventId() {
6338
+ return `event_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
6339
+ }
6340
+ function calculateDropDates(event, newStartDate) {
6341
+ const originalStart = parseISO(event.startDate);
6342
+ const originalEnd = parseISO(event.endDate);
6343
+ const duration = differenceInMinutes(originalEnd, originalStart);
6344
+ const newStart = newStartDate;
6345
+ const newEnd = addMinutes(newStart, duration);
6346
+ return {
6347
+ startDate: newStart.toISOString(),
6348
+ endDate: newEnd.toISOString()
6349
+ };
6350
+ }
6351
+ function snapToInterval(date, intervalMinutes = 15) {
6352
+ const minutes = getMinutes(date);
6353
+ const snappedMinutes = Math.round(minutes / intervalMinutes) * intervalMinutes;
6354
+ return setMinutes(date, snappedMinutes);
6355
+ }
6356
+ var colorClasses = {
6357
+ blue: {
6358
+ dot: "bg-blue-500",
6359
+ bg: "bg-blue-50 dark:bg-blue-950/50",
6360
+ text: "text-blue-600 dark:text-blue-400",
6361
+ border: "border-l-blue-500",
6362
+ solid: "bg-blue-500"
6363
+ },
6364
+ green: {
6365
+ dot: "bg-green-500",
6366
+ bg: "bg-green-50 dark:bg-green-950/50",
6367
+ text: "text-green-600 dark:text-green-400",
6368
+ border: "border-l-green-500",
6369
+ solid: "bg-green-500"
6370
+ },
6371
+ red: {
6372
+ dot: "bg-red-500",
6373
+ bg: "bg-red-50 dark:bg-red-950/50",
6374
+ text: "text-red-600 dark:text-red-400",
6375
+ border: "border-l-red-500",
6376
+ solid: "bg-red-500"
6377
+ },
6378
+ yellow: {
6379
+ dot: "bg-yellow-500",
6380
+ bg: "bg-yellow-50 dark:bg-yellow-950/50",
6381
+ text: "text-yellow-600 dark:text-yellow-400",
6382
+ border: "border-l-yellow-500",
6383
+ solid: "bg-yellow-500"
6384
+ },
6385
+ purple: {
6386
+ dot: "bg-purple-500",
6387
+ bg: "bg-purple-50 dark:bg-purple-950/50",
6388
+ text: "text-purple-600 dark:text-purple-400",
6389
+ border: "border-l-purple-500",
6390
+ solid: "bg-purple-500"
6391
+ },
6392
+ orange: {
6393
+ dot: "bg-primary",
6394
+ bg: "bg-orange-50 dark:bg-orange-950/50",
6395
+ text: "text-primary dark:text-orange-400",
6396
+ border: "border-l-primary",
6397
+ solid: "bg-primary"
6398
+ }
6399
+ };
6400
+ function EventBadge({
6401
+ event,
6402
+ variant = "colored",
6403
+ className,
6404
+ showTime = false,
6405
+ compact = false,
6406
+ isDragging = false,
6407
+ onClick
6408
+ }) {
6409
+ const colors = colorClasses[event.color];
6410
+ const startTime = format(parseISO(event.startDate), "h:mm a");
6411
+ const handleClick = (e) => {
6412
+ e.stopPropagation();
6413
+ onClick?.(event, e);
6414
+ };
6415
+ if (variant === "dot") {
6416
+ return /* @__PURE__ */ jsxs(
6417
+ "button",
6418
+ {
6419
+ type: "button",
6420
+ onClick: handleClick,
6421
+ className: cn(
6422
+ "flex items-center gap-1.5 rounded-sm px-1.5 py-0.5 text-left text-xs transition-colors",
6423
+ "hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6424
+ isDragging && "opacity-50",
6425
+ className
6426
+ ),
6427
+ children: [
6428
+ /* @__PURE__ */ jsx("span", { className: cn("size-2 shrink-0 rounded-full", colors.dot) }),
6429
+ /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: event.title }),
6430
+ showTime && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: startTime })
6431
+ ]
6432
+ }
6433
+ );
6434
+ }
6435
+ if (variant === "mixed") {
6436
+ return /* @__PURE__ */ jsxs(
6437
+ "button",
6438
+ {
6439
+ type: "button",
6440
+ onClick: handleClick,
6441
+ className: cn(
6442
+ "flex items-center gap-1.5 rounded-sm border-l-2 px-1.5 py-0.5 text-left text-xs transition-colors",
6443
+ "hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6444
+ colors.border,
6445
+ isDragging && "opacity-50",
6446
+ className
6447
+ ),
6448
+ children: [
6449
+ /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: event.title }),
6450
+ showTime && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: startTime })
6451
+ ]
6452
+ }
6453
+ );
6454
+ }
6455
+ return /* @__PURE__ */ jsxs(
6456
+ "button",
6457
+ {
6458
+ type: "button",
6459
+ onClick: handleClick,
6460
+ className: cn(
6461
+ "flex flex-col items-start rounded-sm border-l-[3px] text-left text-xs transition-colors",
6462
+ "hover:opacity-80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6463
+ colors.border,
6464
+ colors.bg,
6465
+ colors.text,
6466
+ compact ? "px-1.5 py-0.5" : "px-2 py-1",
6467
+ isDragging && "opacity-50 shadow-lg",
6468
+ className
6469
+ ),
6470
+ children: [
6471
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium max-w-full", children: event.title }),
6472
+ showTime && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: startTime })
6473
+ ]
6474
+ }
6475
+ );
6476
+ }
6477
+ function MoreEvents({ count, onClick, className }) {
6478
+ return /* @__PURE__ */ jsxs(
6479
+ "button",
6480
+ {
6481
+ type: "button",
6482
+ onClick,
6483
+ className: cn(
6484
+ "w-full rounded-sm px-2 py-0.5 text-left text-xs text-muted-foreground transition-colors",
6485
+ "hover:bg-muted hover:text-foreground",
6486
+ className
6487
+ ),
6488
+ children: [
6489
+ count,
6490
+ " more..."
6491
+ ]
6492
+ }
6493
+ );
6494
+ }
6495
+ function TimeIndicator({ className }) {
6496
+ const [now, setNow] = React14.useState(/* @__PURE__ */ new Date());
6497
+ React14.useEffect(() => {
6498
+ const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
6499
+ return () => clearInterval(interval);
6500
+ }, []);
6501
+ const hours = now.getHours();
6502
+ const minutes = now.getMinutes();
6503
+ const topPercent = (hours * 60 + minutes) / (24 * 60) * 100;
6504
+ return /* @__PURE__ */ jsxs(
6505
+ "div",
6506
+ {
6507
+ className: cn(
6508
+ "pointer-events-none absolute left-0 right-0 z-20 flex items-center",
6509
+ className
6510
+ ),
6511
+ style: { top: `${topPercent}%` },
6512
+ children: [
6513
+ /* @__PURE__ */ jsx("div", { className: "size-2.5 -translate-x-1/2 rounded-full bg-red-500" }),
6514
+ /* @__PURE__ */ jsx("div", { className: "h-0.5 flex-1 bg-red-500" })
6515
+ ]
6516
+ }
6517
+ );
6518
+ }
6519
+ function DateBadge({ date, className }) {
6520
+ return /* @__PURE__ */ jsxs(
6521
+ "div",
6522
+ {
6523
+ className: cn(
6524
+ "flex flex-col w-14 overflow-hidden border border-border rounded-md",
6525
+ className
6526
+ ),
6527
+ children: [
6528
+ /* @__PURE__ */ jsx("div", { className: "bg-foreground text-background text-[10px] font-bold text-center py-1.5 uppercase tracking-wider", children: format(date, "MMM") }),
6529
+ /* @__PURE__ */ jsx("div", { className: "bg-background text-foreground text-2xl font-bold text-center py-2.5", children: format(date, "d") })
6530
+ ]
6531
+ }
6532
+ );
6533
+ }
6534
+ var DragContext = React14.createContext(null);
6535
+ function DragProvider({
6536
+ children,
6537
+ snapMinutes = 15,
6538
+ onDragStart,
6539
+ onDragEnd
6540
+ }) {
6541
+ const [draggedEvent, setDraggedEventState] = React14.useState(null);
6542
+ const [isDragging, setIsDragging] = React14.useState(false);
6543
+ const { updateEvent } = useEventCalendar();
6544
+ const setDraggedEvent = React14.useCallback((event) => {
6545
+ setDraggedEventState(event);
6546
+ setIsDragging(!!event);
6547
+ if (event) {
6548
+ onDragStart?.(event);
6549
+ }
6550
+ }, [onDragStart]);
6551
+ const handleDrop = React14.useCallback((newStartDate) => {
6552
+ if (!draggedEvent) return;
6553
+ const snappedDate = snapToInterval(newStartDate, snapMinutes);
6554
+ const { startDate, endDate } = calculateDropDates(draggedEvent, snappedDate);
6555
+ const updatedEvent = {
6556
+ ...draggedEvent,
6557
+ startDate,
6558
+ endDate
6559
+ };
6560
+ updateEvent(updatedEvent);
6561
+ onDragEnd?.(updatedEvent, new Date(startDate), new Date(endDate));
6562
+ setDraggedEvent(null);
6563
+ }, [draggedEvent, snapMinutes, updateEvent, onDragEnd, setDraggedEvent]);
6564
+ const contextValue = React14.useMemo(
6565
+ () => ({
6566
+ draggedEvent,
6567
+ setDraggedEvent,
6568
+ isDragging
6569
+ }),
6570
+ [draggedEvent, setDraggedEvent, isDragging]
6571
+ );
6572
+ return /* @__PURE__ */ jsx(DragContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(DragDropHandler, { onDrop: handleDrop, children }) });
6573
+ }
6574
+ function useDrag() {
6575
+ const context = React14.useContext(DragContext);
6576
+ if (!context) {
6577
+ throw new Error("useDrag must be used within a DragProvider");
6578
+ }
6579
+ return context;
6580
+ }
6581
+ function DragDropHandler({ children, onDrop }) {
6582
+ return /* @__PURE__ */ jsx(Fragment, { children });
6583
+ }
6584
+ function DraggableEvent({
6585
+ event,
6586
+ children,
6587
+ disabled = false
6588
+ }) {
6589
+ const { setDraggedEvent, isDragging, draggedEvent } = useDrag();
6590
+ const isDragged = draggedEvent?.id === event.id;
6591
+ const handleDragStart = (e) => {
6592
+ if (disabled) return;
6593
+ e.dataTransfer.effectAllowed = "move";
6594
+ e.dataTransfer.setData("text/plain", event.id);
6595
+ setDraggedEvent(event);
6596
+ };
6597
+ const handleDragEnd = () => {
6598
+ setDraggedEvent(null);
6599
+ };
6600
+ return /* @__PURE__ */ jsx(
6601
+ "div",
6602
+ {
6603
+ draggable: !disabled,
6604
+ onDragStart: handleDragStart,
6605
+ onDragEnd: handleDragEnd,
6606
+ className: isDragged ? "opacity-50" : "",
6607
+ style: { cursor: disabled ? "default" : "grab" },
6608
+ children
6609
+ }
6610
+ );
6611
+ }
6612
+ function DroppableZone({
6613
+ date,
6614
+ children,
6615
+ onDrop,
6616
+ className
6617
+ }) {
6618
+ const { draggedEvent, setDraggedEvent } = useDrag();
6619
+ const { updateEvent } = useEventCalendar();
6620
+ const [isOver, setIsOver] = React14.useState(false);
6621
+ const handleDragOver = (e) => {
6622
+ e.preventDefault();
6623
+ e.dataTransfer.dropEffect = "move";
6624
+ setIsOver(true);
6625
+ };
6626
+ const handleDragLeave = () => {
6627
+ setIsOver(false);
6628
+ };
6629
+ const handleDrop = (e) => {
6630
+ e.preventDefault();
6631
+ setIsOver(false);
6632
+ if (!draggedEvent) return;
6633
+ const { startDate, endDate } = calculateDropDates(draggedEvent, date);
6634
+ const updatedEvent = {
6635
+ ...draggedEvent,
6636
+ startDate,
6637
+ endDate
6638
+ };
6639
+ updateEvent(updatedEvent);
6640
+ onDrop?.(updatedEvent, date);
6641
+ setDraggedEvent(null);
6642
+ };
6643
+ return /* @__PURE__ */ jsx(
6644
+ "div",
6645
+ {
6646
+ onDragOver: handleDragOver,
6647
+ onDragLeave: handleDragLeave,
6648
+ onDrop: handleDrop,
6649
+ className,
6650
+ "data-drag-over": isOver,
6651
+ children
6652
+ }
6653
+ );
6654
+ }
6655
+ function useDroppable({ date, hour, minute = 0, onDrop }) {
6656
+ const { draggedEvent, setDraggedEvent } = useDrag();
6657
+ const { updateEvent } = useEventCalendar();
6658
+ const [isOver, setIsOver] = React14.useState(false);
6659
+ const dropTargetDate = React14.useMemo(() => {
6660
+ const targetDate = new Date(date);
6661
+ if (hour !== void 0) {
6662
+ targetDate.setHours(hour, minute, 0, 0);
6663
+ }
6664
+ return targetDate;
6665
+ }, [date, hour, minute]);
6666
+ const handleDragOver = React14.useCallback((e) => {
6667
+ e.preventDefault();
6668
+ e.dataTransfer.dropEffect = "move";
6669
+ if (!isOver) setIsOver(true);
6670
+ }, [isOver]);
6671
+ const handleDragLeave = React14.useCallback(() => {
6672
+ setIsOver(false);
6673
+ }, []);
6674
+ const handleDrop = React14.useCallback((e) => {
6675
+ e.preventDefault();
6676
+ setIsOver(false);
6677
+ if (!draggedEvent) return;
6678
+ const { startDate, endDate } = calculateDropDates(draggedEvent, dropTargetDate);
6679
+ const updatedEvent = {
6680
+ ...draggedEvent,
6681
+ startDate,
6682
+ endDate
6683
+ };
6684
+ updateEvent(updatedEvent);
6685
+ onDrop?.(updatedEvent, dropTargetDate);
6686
+ setDraggedEvent(null);
6687
+ }, [draggedEvent, dropTargetDate, updateEvent, onDrop, setDraggedEvent]);
6688
+ return {
6689
+ isOver,
6690
+ dropProps: {
6691
+ onDragOver: handleDragOver,
6692
+ onDragLeave: handleDragLeave,
6693
+ onDrop: handleDrop,
6694
+ "data-drag-over": isOver
6695
+ }
6696
+ };
6697
+ }
6698
+ function useDraggable(event, disabled = false) {
6699
+ const { setDraggedEvent, draggedEvent } = useDrag();
6700
+ const isDragged = draggedEvent?.id === event.id;
6701
+ const handleDragStart = React14.useCallback((e) => {
6702
+ if (disabled) return;
6703
+ e.dataTransfer.effectAllowed = "move";
6704
+ e.dataTransfer.setData("text/plain", event.id);
6705
+ setDraggedEvent(event);
6706
+ }, [disabled, event, setDraggedEvent]);
6707
+ const handleDragEnd = React14.useCallback(() => {
6708
+ setDraggedEvent(null);
6709
+ }, [setDraggedEvent]);
6710
+ return {
6711
+ isDragged,
6712
+ dragProps: {
6713
+ draggable: !disabled,
6714
+ onDragStart: handleDragStart,
6715
+ onDragEnd: handleDragEnd,
6716
+ style: { cursor: disabled ? "default" : "grab" }
6717
+ }
6718
+ };
6719
+ }
6720
+ var WEEK_DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
6721
+ function DraggableEventWrapper({
6722
+ event,
6723
+ children
6724
+ }) {
6725
+ const { isDragged, dragProps } = useDraggable(event);
6726
+ return /* @__PURE__ */ jsx(
6727
+ "div",
6728
+ {
6729
+ ...dragProps,
6730
+ className: cn(
6731
+ "transition-opacity",
6732
+ isDragged && "opacity-50"
6733
+ ),
6734
+ children
6735
+ }
6736
+ );
6737
+ }
6738
+ function MonthView({
6739
+ className,
6740
+ maxEventsPerDay = 3,
6741
+ weekStartsOn = 0,
6742
+ onEventClick,
6743
+ onDateClick,
6744
+ onMoreClick
6745
+ }) {
6746
+ const { selectedDate, badgeVariant, setSelectedDate, setView } = useEventCalendar();
6747
+ const filteredEvents = useFilteredEvents();
6748
+ const { singleDayEvents, multiDayEvents } = React14.useMemo(
6749
+ () => splitEventsByDuration(filteredEvents),
6750
+ [filteredEvents]
6751
+ );
6752
+ const cells = React14.useMemo(
6753
+ () => getCalendarCells(selectedDate),
6754
+ [selectedDate]
6755
+ );
6756
+ const eventPositions = React14.useMemo(
6757
+ () => calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate),
6758
+ [multiDayEvents, singleDayEvents, selectedDate]
6759
+ );
6760
+ const allEvents = [...multiDayEvents, ...singleDayEvents];
6761
+ const handleDateClick = (date) => {
6762
+ setSelectedDate(date);
6763
+ setView("day");
6764
+ onDateClick?.(date);
6765
+ };
6766
+ const handleMoreClick = (date, events) => {
6767
+ setSelectedDate(date);
6768
+ setView("day");
6769
+ onMoreClick?.(date, events);
6770
+ };
6771
+ return /* @__PURE__ */ jsxs("div", { className: cn("", className), children: [
6772
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 divide-x divide-border/50", children: WEEK_DAYS.map((day) => /* @__PURE__ */ jsx(
6773
+ "div",
6774
+ {
6775
+ className: "flex items-center justify-center py-2",
6776
+ children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: day })
6777
+ },
6778
+ day
6779
+ )) }),
6780
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 overflow-hidden", children: cells.map((cell) => /* @__PURE__ */ jsx(
6781
+ DayCell,
6782
+ {
6783
+ cell,
6784
+ events: allEvents,
6785
+ eventPositions,
6786
+ selectedDate,
6787
+ badgeVariant,
6788
+ maxEvents: maxEventsPerDay,
6789
+ onDateClick: handleDateClick,
6790
+ onEventClick,
6791
+ onMoreClick: handleMoreClick
6792
+ },
6793
+ cell.date.toISOString()
6794
+ )) })
6795
+ ] });
6796
+ }
6797
+ function DayCell({
6798
+ cell,
6799
+ events,
6800
+ eventPositions,
6801
+ selectedDate,
6802
+ badgeVariant,
6803
+ maxEvents,
6804
+ onDateClick,
6805
+ onEventClick,
6806
+ onMoreClick
6807
+ }) {
6808
+ const { date, currentMonth } = cell;
6809
+ const isCurrentDay = isToday(date);
6810
+ const isSelectedDay = isSameDay(date, selectedDate);
6811
+ const { isOver, dropProps } = useDroppable({ date });
6812
+ const cellEvents = getMonthCellEvents(date, events, eventPositions);
6813
+ const positionedEvents = cellEvents.filter((e) => e.position !== -1);
6814
+ const hiddenEvents = cellEvents.filter((e) => e.position === -1);
6815
+ const slots = [null, null, null];
6816
+ positionedEvents.forEach((event) => {
6817
+ if (event.position >= 0 && event.position < 3) {
6818
+ slots[event.position] = event;
6819
+ }
6820
+ });
6821
+ const hiddenCount = hiddenEvents.length + positionedEvents.filter((e) => e.position >= 3).length;
6822
+ const isEventStart = (event) => isSameDay(parseISO(event.startDate), date);
6823
+ return /* @__PURE__ */ jsxs(
6824
+ "div",
6825
+ {
6826
+ ...dropProps,
6827
+ className: cn(
6828
+ "relative min-h-[120px] border-b border-r border-border/50 p-1 transition-colors",
6829
+ !currentMonth && "bg-muted/30",
6830
+ isOver && "bg-primary/10 ring-2 ring-primary/50 ring-inset"
6831
+ ),
6832
+ children: [
6833
+ /* @__PURE__ */ jsx(
6834
+ "button",
6835
+ {
6836
+ type: "button",
6837
+ onClick: () => onDateClick(date),
6838
+ className: cn(
6839
+ "mb-1 flex size-7 items-center justify-center text-sm transition-colors",
6840
+ "hover:bg-muted rounded-sm",
6841
+ isCurrentDay && "bg-primary text-primary-foreground hover:bg-primary/90 rounded-sm",
6842
+ isSelectedDay && !isCurrentDay && "bg-muted font-semibold rounded-sm",
6843
+ !currentMonth && "text-muted-foreground"
6844
+ ),
6845
+ children: cell.day
6846
+ }
6847
+ ),
6848
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
6849
+ slots.map((event, index) => {
6850
+ if (!event) {
6851
+ return /* @__PURE__ */ jsx("div", { className: "h-5" }, `empty-${index}`);
6852
+ }
6853
+ const showTitle = isEventStart(event) || startOfDay(date).getDay() === 0;
6854
+ return /* @__PURE__ */ jsx(DraggableEventWrapper, { event, children: /* @__PURE__ */ jsx(
6855
+ EventBadge,
6856
+ {
6857
+ event,
6858
+ variant: badgeVariant,
6859
+ compact: true,
6860
+ showTime: showTitle,
6861
+ onClick: (e) => onEventClick?.(e),
6862
+ className: cn(
6863
+ "w-full",
6864
+ // If not showing title, make it appear as a continuation
6865
+ !showTitle && "rounded-l-none border-l-0"
6866
+ )
6867
+ }
6868
+ ) }, event.id);
6869
+ }),
6870
+ hiddenCount > 0 && /* @__PURE__ */ jsx(
6871
+ MoreEvents,
6872
+ {
6873
+ count: hiddenCount,
6874
+ onClick: () => onMoreClick(date, cellEvents)
6875
+ }
6876
+ )
6877
+ ] })
6878
+ ]
6879
+ }
6880
+ );
6881
+ }
6882
+ function DraggableEventWrapper2({
6883
+ event,
6884
+ children,
6885
+ className,
6886
+ style
6887
+ }) {
6888
+ const { isDragged, dragProps } = useDraggable(event);
6889
+ return /* @__PURE__ */ jsx(
6890
+ "div",
6891
+ {
6892
+ ...dragProps,
6893
+ className: cn(
6894
+ className,
6895
+ "transition-opacity",
6896
+ isDragged && "opacity-50"
6897
+ ),
6898
+ style,
6899
+ children
6900
+ }
6901
+ );
6902
+ }
6903
+ function DroppableTimeSlot({
6904
+ date,
6905
+ hour,
6906
+ minute,
6907
+ className,
6908
+ onClick
6909
+ }) {
6910
+ const { isOver, dropProps } = useDroppable({ date, hour, minute });
6911
+ return /* @__PURE__ */ jsx(
6912
+ "div",
6913
+ {
6914
+ ...dropProps,
6915
+ onClick,
6916
+ className: cn(
6917
+ className,
6918
+ "cursor-pointer transition-colors hover:bg-accent",
6919
+ isOver && "bg-primary/20"
6920
+ )
6921
+ }
6922
+ );
6923
+ }
6924
+ function WeekView({
6925
+ className,
6926
+ weekStartsOn = 0,
6927
+ onEventClick,
6928
+ onDateClick,
6929
+ onTimeClick
6930
+ }) {
6931
+ const {
6932
+ selectedDate,
6933
+ badgeVariant,
6934
+ workingHours,
6935
+ visibleHours
6936
+ } = useEventCalendar();
6937
+ const filteredEvents = useFilteredEvents();
6938
+ const { singleDayEvents, multiDayEvents } = React14.useMemo(
6939
+ () => splitEventsByDuration(filteredEvents),
6940
+ [filteredEvents]
6941
+ );
6942
+ const { hours, earliestEventHour, latestEventHour } = getVisibleHours(
6943
+ visibleHours,
6944
+ singleDayEvents
6945
+ );
6946
+ const weekStart = startOfWeek(selectedDate, { weekStartsOn });
6947
+ const weekDays = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
6948
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6949
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center border-b py-4 text-sm text-muted-foreground sm:hidden", children: [
6950
+ /* @__PURE__ */ jsx("p", { children: "Weekly view is not available on smaller devices." }),
6951
+ /* @__PURE__ */ jsx("p", { children: "Please switch to daily or monthly view." })
6952
+ ] }),
6953
+ /* @__PURE__ */ jsxs("div", { className: cn("hidden flex-col sm:flex", className), children: [
6954
+ /* @__PURE__ */ jsx(
6955
+ WeekViewMultiDayEventsRow,
6956
+ {
6957
+ selectedDate,
6958
+ multiDayEvents
6959
+ }
6960
+ ),
6961
+ /* @__PURE__ */ jsxs("div", { className: "relative z-20 flex border-b border-border/50", children: [
6962
+ /* @__PURE__ */ jsx("div", { className: "w-18" }),
6963
+ /* @__PURE__ */ jsx("div", { className: "grid flex-1 grid-cols-7 divide-x divide-border/50 border-l border-border/50", children: weekDays.map((day, index) => /* @__PURE__ */ jsxs(
6964
+ "span",
6965
+ {
6966
+ className: "py-2 text-center text-xs font-medium text-muted-foreground",
6967
+ children: [
6968
+ format(day, "EE"),
6969
+ " ",
6970
+ /* @__PURE__ */ jsx("span", { className: "ml-1 font-semibold text-foreground", children: format(day, "d") })
6971
+ ]
6972
+ },
6973
+ index
6974
+ )) })
6975
+ ] }),
6976
+ /* @__PURE__ */ jsx(ScrollArea, { className: "h-[736px]", type: "always", children: /* @__PURE__ */ jsxs("div", { className: "flex overflow-hidden", children: [
6977
+ /* @__PURE__ */ jsx("div", { className: "relative w-18", children: hours.map((hour, index) => /* @__PURE__ */ jsx("div", { className: "relative", style: { height: "96px" }, children: /* @__PURE__ */ jsx("div", { className: "absolute -top-3 right-2 flex h-6 items-center", children: index !== 0 && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: format((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), "hh a") }) }) }, hour)) }),
6978
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 border-l border-border/50", children: [
6979
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 divide-x divide-border/50", children: weekDays.map((day, dayIndex) => {
6980
+ const dayEvents = singleDayEvents.filter(
6981
+ (event) => isSameDay(parseISO(event.startDate), day) || isSameDay(parseISO(event.endDate), day)
6982
+ );
6983
+ const groupedEvents = groupEvents(dayEvents);
6984
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
6985
+ hours.map((hour, index) => {
6986
+ const isDisabled = !isWorkingHour(day, hour, workingHours);
6987
+ return /* @__PURE__ */ jsxs(
6988
+ "div",
6989
+ {
6990
+ className: cn(
6991
+ "relative",
6992
+ isDisabled && "bg-[repeating-linear-gradient(45deg,transparent,transparent_5px,rgba(0,0,0,0.04)_5px,rgba(0,0,0,0.04)_10px)] dark:bg-[repeating-linear-gradient(45deg,transparent,transparent_5px,rgba(255,255,255,0.04)_5px,rgba(255,255,255,0.04)_10px)]"
6993
+ ),
6994
+ style: { height: "96px" },
6995
+ children: [
6996
+ index !== 0 && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 border-b border-border/40" }),
6997
+ /* @__PURE__ */ jsx(
6998
+ DroppableTimeSlot,
6999
+ {
7000
+ date: day,
7001
+ hour,
7002
+ minute: 0,
7003
+ className: "absolute inset-x-0 top-0 h-[24px]",
7004
+ onClick: () => onTimeClick?.(day, hour, 0)
7005
+ }
7006
+ ),
7007
+ /* @__PURE__ */ jsx(
7008
+ DroppableTimeSlot,
7009
+ {
7010
+ date: day,
7011
+ hour,
7012
+ minute: 15,
7013
+ className: "absolute inset-x-0 top-[24px] h-[24px]",
7014
+ onClick: () => onTimeClick?.(day, hour, 15)
7015
+ }
7016
+ ),
7017
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-1/2 border-b border-dashed border-border/30" }),
7018
+ /* @__PURE__ */ jsx(
7019
+ DroppableTimeSlot,
7020
+ {
7021
+ date: day,
7022
+ hour,
7023
+ minute: 30,
7024
+ className: "absolute inset-x-0 top-[48px] h-[24px]",
7025
+ onClick: () => onTimeClick?.(day, hour, 30)
7026
+ }
7027
+ ),
7028
+ /* @__PURE__ */ jsx(
7029
+ DroppableTimeSlot,
7030
+ {
7031
+ date: day,
7032
+ hour,
7033
+ minute: 45,
7034
+ className: "absolute inset-x-0 top-[72px] h-[24px]",
7035
+ onClick: () => onTimeClick?.(day, hour, 45)
7036
+ }
7037
+ )
7038
+ ]
7039
+ },
7040
+ hour
7041
+ );
7042
+ }),
7043
+ groupedEvents.map(
7044
+ (group, groupIndex) => group.map((event) => {
7045
+ let style = getEventBlockStyle(
7046
+ event,
7047
+ day,
7048
+ groupIndex,
7049
+ groupedEvents.length,
7050
+ { from: earliestEventHour}
7051
+ );
7052
+ const hasOverlap = groupedEvents.some(
7053
+ (otherGroup, otherIndex) => otherIndex !== groupIndex && otherGroup.some(
7054
+ (otherEvent) => areIntervalsOverlapping(
7055
+ {
7056
+ start: parseISO(event.startDate),
7057
+ end: parseISO(event.endDate)
7058
+ },
7059
+ {
7060
+ start: parseISO(otherEvent.startDate),
7061
+ end: parseISO(otherEvent.endDate)
7062
+ }
7063
+ )
7064
+ )
7065
+ );
7066
+ if (!hasOverlap) {
7067
+ style = { ...style, width: "100%", left: "0%" };
7068
+ }
7069
+ return /* @__PURE__ */ jsx(
7070
+ DraggableEventWrapper2,
7071
+ {
7072
+ event,
7073
+ className: "absolute px-0.5 py-0.5",
7074
+ style,
7075
+ children: /* @__PURE__ */ jsx(
7076
+ EventBadge,
7077
+ {
7078
+ event,
7079
+ variant: badgeVariant,
7080
+ showTime: true,
7081
+ onClick: (e) => onEventClick?.(e),
7082
+ className: "h-full w-full"
7083
+ }
7084
+ )
7085
+ },
7086
+ event.id
7087
+ );
7088
+ })
7089
+ )
7090
+ ] }, dayIndex);
7091
+ }) }),
7092
+ weekDays.some((day) => isToday(day)) && /* @__PURE__ */ jsx(
7093
+ CalendarTimeline,
7094
+ {
7095
+ firstVisibleHour: earliestEventHour,
7096
+ lastVisibleHour: latestEventHour
7097
+ }
7098
+ )
7099
+ ] })
7100
+ ] }) })
7101
+ ] })
7102
+ ] });
7103
+ }
7104
+ function WeekViewMultiDayEventsRow({
7105
+ selectedDate,
7106
+ multiDayEvents
7107
+ }) {
7108
+ const { badgeVariant } = useEventCalendar();
7109
+ if (multiDayEvents.length === 0) return null;
7110
+ const weekStart = startOfWeek(selectedDate);
7111
+ const weekDays = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
7112
+ return /* @__PURE__ */ jsxs("div", { className: "hidden border-b sm:flex", children: [
7113
+ /* @__PURE__ */ jsx("div", { className: "w-18 shrink-0" }),
7114
+ /* @__PURE__ */ jsx("div", { className: "grid flex-1 grid-cols-7 divide-x border-l", children: weekDays.map((day, index) => {
7115
+ const dayMultiEvents = multiDayEvents.filter((event) => {
7116
+ const start = parseISO(event.startDate);
7117
+ const end = parseISO(event.endDate);
7118
+ return day >= start && day <= end;
7119
+ });
7120
+ return /* @__PURE__ */ jsxs("div", { className: "min-h-[32px] space-y-1 p-1", children: [
7121
+ dayMultiEvents.slice(0, 2).map((event) => /* @__PURE__ */ jsx(
7122
+ EventBadge,
7123
+ {
7124
+ event,
7125
+ variant: badgeVariant,
7126
+ compact: true,
7127
+ className: "w-full"
7128
+ },
7129
+ event.id
7130
+ )),
7131
+ dayMultiEvents.length > 2 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground text-center", children: [
7132
+ "+",
7133
+ dayMultiEvents.length - 2,
7134
+ " more"
7135
+ ] })
7136
+ ] }, index);
7137
+ }) })
7138
+ ] });
7139
+ }
7140
+ function CalendarTimeline({
7141
+ firstVisibleHour,
7142
+ lastVisibleHour
7143
+ }) {
7144
+ const [currentTime, setCurrentTime] = React14.useState(/* @__PURE__ */ new Date());
7145
+ React14.useEffect(() => {
7146
+ const interval = setInterval(() => {
7147
+ setCurrentTime(/* @__PURE__ */ new Date());
7148
+ }, 6e4);
7149
+ return () => clearInterval(interval);
7150
+ }, []);
7151
+ const currentHour = currentTime.getHours();
7152
+ const currentMinute = currentTime.getMinutes();
7153
+ if (currentHour < firstVisibleHour || currentHour >= lastVisibleHour) {
7154
+ return null;
7155
+ }
7156
+ const minutesSinceStart = (currentHour - firstVisibleHour) * 60 + currentMinute;
7157
+ const totalMinutes = (lastVisibleHour - firstVisibleHour) * 60;
7158
+ const topPercent = minutesSinceStart / totalMinutes * 100;
7159
+ return /* @__PURE__ */ jsxs(
7160
+ "div",
7161
+ {
7162
+ className: "pointer-events-none absolute inset-x-0 z-30 flex items-center",
7163
+ style: { top: `${topPercent}%` },
7164
+ children: [
7165
+ /* @__PURE__ */ jsx("div", { className: "size-3 -translate-x-1/2 rounded-full bg-red-500" }),
7166
+ /* @__PURE__ */ jsx("div", { className: "h-0.5 flex-1 bg-red-500" })
7167
+ ]
7168
+ }
7169
+ );
7170
+ }
7171
+ function DraggableEventWrapper3({
7172
+ event,
7173
+ children,
7174
+ className,
7175
+ style
7176
+ }) {
7177
+ const { isDragged, dragProps } = useDraggable(event);
7178
+ return /* @__PURE__ */ jsx(
7179
+ "div",
7180
+ {
7181
+ ...dragProps,
7182
+ className: cn(
7183
+ className,
7184
+ "transition-opacity",
7185
+ isDragged && "opacity-50"
7186
+ ),
7187
+ style,
7188
+ children
7189
+ }
7190
+ );
7191
+ }
7192
+ function DroppableTimeSlot2({
7193
+ date,
7194
+ hour,
7195
+ minute,
7196
+ className,
7197
+ onClick
7198
+ }) {
7199
+ const { isOver, dropProps } = useDroppable({ date, hour, minute });
7200
+ return /* @__PURE__ */ jsx(
7201
+ "div",
7202
+ {
7203
+ ...dropProps,
7204
+ onClick,
7205
+ className: cn(
7206
+ className,
7207
+ "cursor-pointer transition-colors hover:bg-accent",
7208
+ isOver && "bg-primary/20"
7209
+ )
7210
+ }
7211
+ );
7212
+ }
7213
+ function DayView({
7214
+ className,
7215
+ showSidebar = true,
7216
+ onEventClick,
7217
+ onTimeClick
7218
+ }) {
7219
+ const {
7220
+ selectedDate,
7221
+ setSelectedDate,
7222
+ badgeVariant,
7223
+ users,
7224
+ workingHours,
7225
+ visibleHours
7226
+ } = useEventCalendar();
7227
+ const filteredEvents = useFilteredEvents();
7228
+ const { singleDayEvents, multiDayEvents } = React14.useMemo(
7229
+ () => splitEventsByDuration(filteredEvents),
7230
+ [filteredEvents]
7231
+ );
7232
+ const { hours, earliestEventHour, latestEventHour } = getVisibleHours(
7233
+ visibleHours,
7234
+ singleDayEvents
7235
+ );
7236
+ const currentEvents = React14.useMemo(() => {
7237
+ if (!isToday(selectedDate)) return [];
7238
+ return getCurrentEvents(singleDayEvents);
7239
+ }, [singleDayEvents, selectedDate]);
7240
+ const dayEvents = singleDayEvents.filter((event) => {
7241
+ const eventDate = parseISO(event.startDate);
7242
+ return eventDate.getDate() === selectedDate.getDate() && eventDate.getMonth() === selectedDate.getMonth() && eventDate.getFullYear() === selectedDate.getFullYear();
7243
+ });
7244
+ const groupedEvents = groupEvents(dayEvents);
7245
+ const handleDateSelect = (date) => {
7246
+ if (date) {
7247
+ setSelectedDate(date);
7248
+ }
7249
+ };
7250
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex", className), children: [
7251
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col", children: [
7252
+ multiDayEvents.length > 0 && /* @__PURE__ */ jsx(
7253
+ DayViewMultiDayEventsRow,
7254
+ {
7255
+ selectedDate,
7256
+ multiDayEvents
7257
+ }
7258
+ ),
7259
+ /* @__PURE__ */ jsxs("div", { className: "relative z-20 flex border-b border-border/50", children: [
7260
+ /* @__PURE__ */ jsx("div", { className: "w-18" }),
7261
+ /* @__PURE__ */ jsxs("span", { className: "flex-1 border-l border-border/50 py-2 text-center text-xs font-medium text-muted-foreground", children: [
7262
+ format(selectedDate, "EE"),
7263
+ " ",
7264
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: format(selectedDate, "d") })
7265
+ ] })
7266
+ ] }),
7267
+ /* @__PURE__ */ jsx(ScrollArea, { className: "h-[800px]", type: "always", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
7268
+ /* @__PURE__ */ jsx("div", { className: "relative w-18", children: hours.map((hour, index) => /* @__PURE__ */ jsx("div", { className: "relative", style: { height: "96px" }, children: /* @__PURE__ */ jsx("div", { className: "absolute -top-3 right-2 flex h-6 items-center", children: index !== 0 && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: format((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), "hh a") }) }) }, hour)) }),
7269
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 border-l border-border/50", children: [
7270
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
7271
+ hours.map((hour, index) => {
7272
+ const isDisabled = !isWorkingHour(selectedDate, hour, workingHours);
7273
+ return /* @__PURE__ */ jsxs(
7274
+ "div",
7275
+ {
7276
+ className: cn(
7277
+ "relative",
7278
+ isDisabled && "bg-[repeating-linear-gradient(45deg,transparent,transparent_5px,rgba(0,0,0,0.04)_5px,rgba(0,0,0,0.04)_10px)] dark:bg-[repeating-linear-gradient(45deg,transparent,transparent_5px,rgba(255,255,255,0.04)_5px,rgba(255,255,255,0.04)_10px)]"
7279
+ ),
7280
+ style: { height: "96px" },
7281
+ children: [
7282
+ index !== 0 && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 border-b border-border/40" }),
7283
+ /* @__PURE__ */ jsx(
7284
+ DroppableTimeSlot2,
7285
+ {
7286
+ date: selectedDate,
7287
+ hour,
7288
+ minute: 0,
7289
+ className: "absolute inset-x-0 top-0 h-[24px]",
7290
+ onClick: () => onTimeClick?.(selectedDate, hour, 0)
7291
+ }
7292
+ ),
7293
+ /* @__PURE__ */ jsx(
7294
+ DroppableTimeSlot2,
7295
+ {
7296
+ date: selectedDate,
7297
+ hour,
7298
+ minute: 15,
7299
+ className: "absolute inset-x-0 top-[24px] h-[24px]",
7300
+ onClick: () => onTimeClick?.(selectedDate, hour, 15)
7301
+ }
7302
+ ),
7303
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-1/2 border-b border-dashed border-border/30" }),
7304
+ /* @__PURE__ */ jsx(
7305
+ DroppableTimeSlot2,
7306
+ {
7307
+ date: selectedDate,
7308
+ hour,
7309
+ minute: 30,
7310
+ className: "absolute inset-x-0 top-[48px] h-[24px]",
7311
+ onClick: () => onTimeClick?.(selectedDate, hour, 30)
7312
+ }
7313
+ ),
7314
+ /* @__PURE__ */ jsx(
7315
+ DroppableTimeSlot2,
7316
+ {
7317
+ date: selectedDate,
7318
+ hour,
7319
+ minute: 45,
7320
+ className: "absolute inset-x-0 top-[72px] h-[24px]",
7321
+ onClick: () => onTimeClick?.(selectedDate, hour, 45)
7322
+ }
7323
+ )
7324
+ ]
7325
+ },
7326
+ hour
7327
+ );
7328
+ }),
7329
+ groupedEvents.map(
7330
+ (group, groupIndex) => group.map((event) => {
7331
+ let style = getEventBlockStyle(
7332
+ event,
7333
+ selectedDate,
7334
+ groupIndex,
7335
+ groupedEvents.length,
7336
+ { from: earliestEventHour}
7337
+ );
7338
+ const hasOverlap = groupedEvents.some(
7339
+ (otherGroup, otherIndex) => otherIndex !== groupIndex && otherGroup.some(
7340
+ (otherEvent) => areIntervalsOverlapping(
7341
+ {
7342
+ start: parseISO(event.startDate),
7343
+ end: parseISO(event.endDate)
7344
+ },
7345
+ {
7346
+ start: parseISO(otherEvent.startDate),
7347
+ end: parseISO(otherEvent.endDate)
7348
+ }
7349
+ )
7350
+ )
7351
+ );
7352
+ if (!hasOverlap) {
7353
+ style = { ...style, width: "100%", left: "0%" };
7354
+ }
7355
+ return /* @__PURE__ */ jsx(
7356
+ DraggableEventWrapper3,
7357
+ {
7358
+ event,
7359
+ className: "absolute px-1 py-0.5",
7360
+ style,
7361
+ children: /* @__PURE__ */ jsx(
7362
+ EventBadge,
7363
+ {
7364
+ event,
7365
+ variant: badgeVariant,
7366
+ showTime: true,
7367
+ onClick: (e) => onEventClick?.(e),
7368
+ className: "h-full w-full"
7369
+ }
7370
+ )
7371
+ },
7372
+ event.id
7373
+ );
7374
+ })
7375
+ )
7376
+ ] }),
7377
+ isToday(selectedDate) && /* @__PURE__ */ jsx(
7378
+ CalendarTimeline2,
7379
+ {
7380
+ firstVisibleHour: earliestEventHour,
7381
+ lastVisibleHour: latestEventHour
7382
+ }
7383
+ )
7384
+ ] })
7385
+ ] }) })
7386
+ ] }),
7387
+ showSidebar && /* @__PURE__ */ jsxs("div", { className: "hidden w-64 divide-y border-l md:block", children: [
7388
+ /* @__PURE__ */ jsx(
7389
+ Calendar,
7390
+ {
7391
+ className: "mx-auto w-fit",
7392
+ mode: "single",
7393
+ selected: selectedDate,
7394
+ onSelect: handleDateSelect
7395
+ }
7396
+ ),
7397
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-3", children: [
7398
+ currentEvents.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 px-4 pt-4", children: [
7399
+ /* @__PURE__ */ jsxs("span", { className: "relative mt-[5px] flex size-2.5", children: [
7400
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex size-full animate-ping rounded-full bg-green-400 opacity-75" }),
7401
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex size-2.5 rounded-full bg-green-600" })
7402
+ ] }),
7403
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Happening now" })
7404
+ ] }) : /* @__PURE__ */ jsx("p", { className: "p-4 text-center text-sm italic text-muted-foreground", children: "No appointments or consultations at the moment" }),
7405
+ currentEvents.length > 0 && /* @__PURE__ */ jsx(ScrollArea, { className: "h-[422px] px-4", type: "always", children: /* @__PURE__ */ jsx("div", { className: "space-y-6 pb-4", children: currentEvents.map((event) => {
7406
+ const user = users.find((u) => u.id === event.user.id);
7407
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
7408
+ /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm font-semibold", children: event.title }),
7409
+ user && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
7410
+ /* @__PURE__ */ jsx(User, { className: "size-3.5" }),
7411
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: user.name })
7412
+ ] }),
7413
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
7414
+ /* @__PURE__ */ jsx(Calendar$1, { className: "size-3.5" }),
7415
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: format(/* @__PURE__ */ new Date(), "MMM d, yyyy") })
7416
+ ] }),
7417
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
7418
+ /* @__PURE__ */ jsx(Clock, { className: "size-3.5" }),
7419
+ /* @__PURE__ */ jsxs("span", { className: "text-sm", children: [
7420
+ format(parseISO(event.startDate), "h:mm a"),
7421
+ " -",
7422
+ " ",
7423
+ format(parseISO(event.endDate), "h:mm a")
7424
+ ] })
7425
+ ] })
7426
+ ] }, event.id);
7427
+ }) }) })
7428
+ ] })
7429
+ ] })
7430
+ ] });
7431
+ }
7432
+ function DayViewMultiDayEventsRow({
7433
+ selectedDate,
7434
+ multiDayEvents
7435
+ }) {
7436
+ const { badgeVariant } = useEventCalendar();
7437
+ const relevantEvents = multiDayEvents.filter((event) => {
7438
+ const start = parseISO(event.startDate);
7439
+ const end = parseISO(event.endDate);
7440
+ return selectedDate >= start && selectedDate <= end;
7441
+ });
7442
+ if (relevantEvents.length === 0) return null;
7443
+ return /* @__PURE__ */ jsxs("div", { className: "flex border-b", children: [
7444
+ /* @__PURE__ */ jsx("div", { className: "w-18 shrink-0" }),
7445
+ /* @__PURE__ */ jsx("div", { className: "flex-1 space-y-1 border-l p-2", children: relevantEvents.map((event) => /* @__PURE__ */ jsx(
7446
+ EventBadge,
7447
+ {
7448
+ event,
7449
+ variant: badgeVariant,
7450
+ className: "w-full"
7451
+ },
7452
+ event.id
7453
+ )) })
7454
+ ] });
7455
+ }
7456
+ function CalendarTimeline2({
7457
+ firstVisibleHour,
7458
+ lastVisibleHour
7459
+ }) {
7460
+ const [currentTime, setCurrentTime] = React14.useState(/* @__PURE__ */ new Date());
7461
+ React14.useEffect(() => {
7462
+ const interval = setInterval(() => {
7463
+ setCurrentTime(/* @__PURE__ */ new Date());
7464
+ }, 6e4);
7465
+ return () => clearInterval(interval);
7466
+ }, []);
7467
+ const currentHour = currentTime.getHours();
7468
+ const currentMinute = currentTime.getMinutes();
7469
+ if (currentHour < firstVisibleHour || currentHour >= lastVisibleHour) {
7470
+ return null;
7471
+ }
7472
+ const minutesSinceStart = (currentHour - firstVisibleHour) * 60 + currentMinute;
7473
+ const totalMinutes = (lastVisibleHour - firstVisibleHour) * 60;
7474
+ const topPercent = minutesSinceStart / totalMinutes * 100;
7475
+ return /* @__PURE__ */ jsxs(
7476
+ "div",
7477
+ {
7478
+ className: "pointer-events-none absolute inset-x-0 z-30 flex items-center",
7479
+ style: { top: `${topPercent}%` },
7480
+ children: [
7481
+ /* @__PURE__ */ jsx("div", { className: "size-3 -translate-x-1/2 rounded-full bg-red-500" }),
7482
+ /* @__PURE__ */ jsx("div", { className: "h-0.5 flex-1 bg-red-500" })
7483
+ ]
7484
+ }
7485
+ );
7486
+ }
7487
+ function YearView({
7488
+ className,
7489
+ weekStartsOn = 0,
7490
+ onMonthClick,
7491
+ onDateClick
7492
+ }) {
7493
+ const { selectedDate, setSelectedDate, setView } = useEventCalendar();
7494
+ const filteredEvents = useFilteredEvents();
7495
+ const months = React14.useMemo(() => {
7496
+ const yearStart = startOfYear(selectedDate);
7497
+ return Array.from({ length: 12 }, (_, i) => addMonths(yearStart, i));
7498
+ }, [selectedDate]);
7499
+ const handleMonthClick = (date) => {
7500
+ setSelectedDate(date);
7501
+ setView("month");
7502
+ onMonthClick?.(date);
7503
+ };
7504
+ const handleDateClick = (date) => {
7505
+ setSelectedDate(date);
7506
+ setView("day");
7507
+ onDateClick?.(date);
7508
+ };
7509
+ return /* @__PURE__ */ jsx(ScrollArea, { className: cn("h-full", className), type: "always", children: /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: months.map((month) => /* @__PURE__ */ jsx(
7510
+ YearViewMonth,
7511
+ {
7512
+ month,
7513
+ events: filteredEvents,
7514
+ onMonthClick: () => handleMonthClick(month),
7515
+ onDateClick: handleDateClick
7516
+ },
7517
+ month.toString()
7518
+ )) }) }) });
7519
+ }
7520
+ function YearViewMonth({
7521
+ month,
7522
+ events,
7523
+ onMonthClick,
7524
+ onDateClick
7525
+ }) {
7526
+ const cells = getCalendarCells(month);
7527
+ const monthEvents = events.filter((event) => {
7528
+ const eventStart = parseISO(event.startDate);
7529
+ return isSameMonth(eventStart, month);
7530
+ });
7531
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-sm border border-border/50 bg-card p-3", children: [
7532
+ /* @__PURE__ */ jsxs(
7533
+ "button",
7534
+ {
7535
+ type: "button",
7536
+ onClick: onMonthClick,
7537
+ className: "mb-2 w-full text-left text-sm font-semibold transition-colors hover:text-primary",
7538
+ children: [
7539
+ format(month, "MMMM"),
7540
+ monthEvents.length > 0 && /* @__PURE__ */ jsxs("span", { className: "ml-2 text-xs font-normal text-muted-foreground", children: [
7541
+ "(",
7542
+ monthEvents.length,
7543
+ ")"
7544
+ ] })
7545
+ ]
7546
+ }
7547
+ ),
7548
+ /* @__PURE__ */ jsx("div", { className: "mb-1 grid grid-cols-7", children: ["S", "M", "T", "W", "T", "F", "S"].map((day, i) => /* @__PURE__ */ jsx(
7549
+ "div",
7550
+ {
7551
+ className: "text-center text-[10px] font-medium text-muted-foreground",
7552
+ children: day
7553
+ },
7554
+ i
7555
+ )) }),
7556
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7", children: cells.map((cell) => /* @__PURE__ */ jsx(
7557
+ YearViewDayCell,
7558
+ {
7559
+ cell,
7560
+ month,
7561
+ events,
7562
+ onDateClick
7563
+ },
7564
+ cell.date.toISOString()
7565
+ )) })
7566
+ ] });
7567
+ }
7568
+ function YearViewDayCell({
7569
+ cell,
7570
+ month,
7571
+ events,
7572
+ onDateClick
7573
+ }) {
7574
+ const { date, currentMonth } = cell;
7575
+ const isCurrentDay = isToday(date);
7576
+ const dayEvents = events.filter((event) => {
7577
+ const eventStart = parseISO(event.startDate);
7578
+ const eventEnd = parseISO(event.endDate);
7579
+ return date >= eventStart && date <= eventEnd || isSameDay(eventStart, date) || isSameDay(eventEnd, date);
7580
+ });
7581
+ const hasEvents = dayEvents.length > 0;
7582
+ if (!currentMonth) {
7583
+ return /* @__PURE__ */ jsx("div", { className: "aspect-square" });
7584
+ }
7585
+ return /* @__PURE__ */ jsxs(
7586
+ "button",
7587
+ {
7588
+ type: "button",
7589
+ onClick: () => onDateClick(date),
7590
+ className: cn(
7591
+ "relative flex aspect-square items-center justify-center text-[11px] transition-colors",
7592
+ "hover:bg-muted rounded-sm",
7593
+ isCurrentDay && "bg-primary text-primary-foreground rounded-sm hover:bg-primary/90"
7594
+ ),
7595
+ children: [
7596
+ cell.day,
7597
+ hasEvents && !isCurrentDay && /* @__PURE__ */ jsx("span", { className: "absolute bottom-0.5 left-1/2 size-1 -translate-x-1/2 rounded-full bg-primary" })
7598
+ ]
7599
+ }
7600
+ );
7601
+ }
7602
+ var colorClasses2 = {
7603
+ blue: { border: "border-l-blue-500", bg: "bg-blue-50 dark:bg-blue-950/20" },
7604
+ green: { border: "border-l-green-500", bg: "bg-green-50 dark:bg-green-950/20" },
7605
+ red: { border: "border-l-red-500", bg: "bg-red-50 dark:bg-red-950/20" },
7606
+ yellow: { border: "border-l-yellow-500", bg: "bg-yellow-50 dark:bg-yellow-950/20" },
7607
+ purple: { border: "border-l-purple-500", bg: "bg-purple-50 dark:bg-purple-950/20" },
7608
+ orange: { border: "border-l-primary", bg: "bg-orange-50 dark:bg-orange-950/20" }
7609
+ };
7610
+ function AgendaView({
7611
+ className,
7612
+ emptyMessage = "No events scheduled for the selected month",
7613
+ onEventClick,
7614
+ onDateClick
7615
+ }) {
7616
+ const { selectedDate, setSelectedDate, setView } = useEventCalendar();
7617
+ const filteredEvents = useFilteredEvents();
7618
+ const { singleDayEvents, multiDayEvents } = React14.useMemo(
7619
+ () => splitEventsByDuration(filteredEvents),
7620
+ [filteredEvents]
7621
+ );
7622
+ const eventsByDay = React14.useMemo(() => {
7623
+ const allDates = /* @__PURE__ */ new Map();
7624
+ singleDayEvents.forEach((event) => {
7625
+ const eventDate = parseISO(event.startDate);
7626
+ if (!isSameMonth(eventDate, selectedDate)) return;
7627
+ const dateKey = format(eventDate, "yyyy-MM-dd");
7628
+ if (!allDates.has(dateKey)) {
7629
+ allDates.set(dateKey, {
7630
+ date: startOfDay(eventDate),
7631
+ events: [],
7632
+ multiDayEvents: []
7633
+ });
7634
+ }
7635
+ allDates.get(dateKey)?.events.push(event);
7636
+ });
7637
+ multiDayEvents.forEach((event) => {
7638
+ const eventStart = parseISO(event.startDate);
7639
+ const eventEnd = parseISO(event.endDate);
7640
+ let currentDate = startOfDay(eventStart);
7641
+ const lastDate = endOfDay(eventEnd);
7642
+ while (currentDate <= lastDate) {
7643
+ if (isSameMonth(currentDate, selectedDate)) {
7644
+ const dateKey = format(currentDate, "yyyy-MM-dd");
7645
+ if (!allDates.has(dateKey)) {
7646
+ allDates.set(dateKey, {
7647
+ date: new Date(currentDate),
7648
+ events: [],
7649
+ multiDayEvents: []
7650
+ });
7651
+ }
7652
+ allDates.get(dateKey)?.multiDayEvents.push(event);
7653
+ }
7654
+ currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1));
7655
+ }
7656
+ });
7657
+ return Array.from(allDates.values()).sort(
7658
+ (a, b) => a.date.getTime() - b.date.getTime()
7659
+ );
7660
+ }, [singleDayEvents, multiDayEvents, selectedDate]);
7661
+ const hasAnyEvents = singleDayEvents.length > 0 || multiDayEvents.length > 0;
7662
+ const handleDateClick = (date) => {
7663
+ setSelectedDate(date);
7664
+ setView("day");
7665
+ onDateClick?.(date);
7666
+ };
7667
+ return /* @__PURE__ */ jsx("div", { className: cn("h-[800px]", className), children: /* @__PURE__ */ jsx(ScrollArea, { className: "h-full", type: "always", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6 p-4", children: [
7668
+ eventsByDay.map((dayGroup) => /* @__PURE__ */ jsx(
7669
+ AgendaDayGroup,
7670
+ {
7671
+ date: dayGroup.date,
7672
+ events: dayGroup.events,
7673
+ multiDayEvents: dayGroup.multiDayEvents,
7674
+ onDateClick: handleDateClick,
7675
+ onEventClick
7676
+ },
7677
+ format(dayGroup.date, "yyyy-MM-dd")
7678
+ )),
7679
+ !hasAnyEvents && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center gap-2 py-20 text-muted-foreground", children: [
7680
+ /* @__PURE__ */ jsx(CalendarX2, { className: "size-10" }),
7681
+ /* @__PURE__ */ jsx("p", { className: "text-sm md:text-base", children: emptyMessage })
7682
+ ] })
7683
+ ] }) }) });
7684
+ }
7685
+ function AgendaDayGroup({
7686
+ date,
7687
+ events,
7688
+ multiDayEvents,
7689
+ onDateClick,
7690
+ onEventClick
7691
+ }) {
7692
+ const isCurrentDay = isToday(date);
7693
+ return /* @__PURE__ */ jsxs("div", { children: [
7694
+ /* @__PURE__ */ jsxs(
7695
+ "button",
7696
+ {
7697
+ type: "button",
7698
+ onClick: () => onDateClick(date),
7699
+ className: cn(
7700
+ "mb-3 flex items-center gap-2 text-left transition-colors hover:text-primary",
7701
+ isCurrentDay && "text-primary"
7702
+ ),
7703
+ children: [
7704
+ /* @__PURE__ */ jsx(
7705
+ "span",
7706
+ {
7707
+ className: cn(
7708
+ "flex size-8 items-center justify-center rounded-full text-sm font-bold",
7709
+ isCurrentDay && "bg-primary text-primary-foreground"
7710
+ ),
7711
+ children: format(date, "d")
7712
+ }
7713
+ ),
7714
+ /* @__PURE__ */ jsxs("div", { children: [
7715
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: format(date, "EEEE") }),
7716
+ /* @__PURE__ */ jsx("span", { className: "ml-2 text-muted-foreground", children: format(date, "MMMM d, yyyy") })
7717
+ ] })
7718
+ ]
7719
+ }
7720
+ ),
7721
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 pl-10", children: [
7722
+ multiDayEvents.map((event) => /* @__PURE__ */ jsx(
7723
+ AgendaEventCard,
7724
+ {
7725
+ event,
7726
+ isMultiDay: true,
7727
+ onClick: () => onEventClick?.(event)
7728
+ },
7729
+ `multi-${event.id}`
7730
+ )),
7731
+ events.map((event) => /* @__PURE__ */ jsx(
7732
+ AgendaEventCard,
7733
+ {
7734
+ event,
7735
+ onClick: () => onEventClick?.(event)
7736
+ },
7737
+ event.id
7738
+ ))
7739
+ ] })
7740
+ ] });
7741
+ }
7742
+ function AgendaEventCard({ event, isMultiDay, onClick }) {
7743
+ const colors = colorClasses2[event.color];
7744
+ const startTime = format(parseISO(event.startDate), "h:mm a");
7745
+ const endTime = format(parseISO(event.endDate), "h:mm a");
7746
+ const getInitials = (name) => {
7747
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
7748
+ };
7749
+ return /* @__PURE__ */ jsxs(
7750
+ "button",
7751
+ {
7752
+ type: "button",
7753
+ onClick,
7754
+ className: cn(
7755
+ "flex w-full items-start gap-3 rounded-lg border-l-4 p-3 text-left transition-colors",
7756
+ "hover:opacity-90",
7757
+ colors.border,
7758
+ colors.bg
7759
+ ),
7760
+ children: [
7761
+ /* @__PURE__ */ jsxs(Avatar, { className: "size-10 shrink-0", children: [
7762
+ /* @__PURE__ */ jsx(AvatarImage, { src: event.user.picturePath, alt: event.user.name }),
7763
+ /* @__PURE__ */ jsx(AvatarFallback, { children: getInitials(event.user.name) })
7764
+ ] }),
7765
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
7766
+ isMultiDay && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Multi-day event" }),
7767
+ /* @__PURE__ */ jsx("h3", { className: "font-semibold truncate", children: event.title }),
7768
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: event.user.name }),
7769
+ /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
7770
+ startTime,
7771
+ " - ",
7772
+ endTime
7773
+ ] }),
7774
+ event.description && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground line-clamp-2", children: event.description })
7775
+ ] })
7776
+ ]
7777
+ }
7778
+ );
7779
+ }
7780
+ var VIEW_CONFIG = [
7781
+ { view: "day", icon: List, label: "View by day" },
7782
+ { view: "week", icon: Columns, label: "View by week" },
7783
+ { view: "month", icon: Grid2x2, label: "View by month" },
7784
+ { view: "year", icon: Grid3x3, label: "View by year" },
7785
+ { view: "agenda", icon: CalendarRange, label: "View by agenda" }
7786
+ ];
7787
+ function CalendarHeader({
7788
+ className,
7789
+ showViewSwitcher = true,
7790
+ showUserFilter = true,
7791
+ showBadgeVariant = false,
7792
+ // Hidden by default, controlled via settings
7793
+ showToday = true,
7794
+ showAddButton = true,
7795
+ onAddClick
7796
+ }) {
7797
+ const {
7798
+ selectedDate,
7799
+ view,
7800
+ setView,
7801
+ setSelectedDate,
7802
+ selectedUserId,
7803
+ setSelectedUserId,
7804
+ users,
7805
+ badgeVariant,
7806
+ setBadgeVariant,
7807
+ goToPrevious,
7808
+ goToNext
7809
+ } = useEventCalendar();
7810
+ const filteredEvents = useFilteredEvents();
7811
+ const eventCount = filteredEvents.length;
7812
+ const { start: rangeStart, end: rangeEnd } = getViewDateRange(selectedDate, view);
7813
+ const dateRangeLabel = formatDateRange(rangeStart, rangeEnd);
7814
+ const getInitials = (name) => {
7815
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
7816
+ };
7817
+ const handleTodayClick = () => {
7818
+ setSelectedDate(/* @__PURE__ */ new Date());
7819
+ };
7820
+ const today = /* @__PURE__ */ new Date();
7821
+ return /* @__PURE__ */ jsxs(
7822
+ "div",
7823
+ {
7824
+ className: cn(
7825
+ "flex flex-col gap-4 border-b border-border p-4 lg:flex-row lg:items-center lg:justify-between",
7826
+ className
7827
+ ),
7828
+ children: [
7829
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
7830
+ /* @__PURE__ */ jsxs(
7831
+ "button",
7832
+ {
7833
+ type: "button",
7834
+ onClick: handleTodayClick,
7835
+ className: "flex size-14 flex-col items-start overflow-hidden rounded-lg border focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
7836
+ children: [
7837
+ /* @__PURE__ */ jsx("p", { className: "flex h-6 w-full items-center justify-center bg-primary text-center text-xs font-semibold text-primary-foreground", children: format(today, "MMM").toUpperCase() }),
7838
+ /* @__PURE__ */ jsx("p", { className: "flex w-full flex-1 items-center justify-center text-lg font-bold", children: today.getDate() })
7839
+ ]
7840
+ }
7841
+ ),
7842
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
7843
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7844
+ /* @__PURE__ */ jsxs("span", { className: "text-lg font-semibold", children: [
7845
+ format(selectedDate, "MMMM"),
7846
+ " ",
7847
+ selectedDate.getFullYear()
7848
+ ] }),
7849
+ /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "px-1.5", children: [
7850
+ eventCount,
7851
+ " event",
7852
+ eventCount !== 1 ? "s" : ""
7853
+ ] })
7854
+ ] }),
7855
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7856
+ /* @__PURE__ */ jsxs(
7857
+ Button,
7858
+ {
7859
+ variant: "outline",
7860
+ size: "icon",
7861
+ className: "size-7 [&_svg]:size-4",
7862
+ onClick: goToPrevious,
7863
+ children: [
7864
+ /* @__PURE__ */ jsx(ChevronLeft, {}),
7865
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Previous" })
7866
+ ]
7867
+ }
7868
+ ),
7869
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: dateRangeLabel }),
7870
+ /* @__PURE__ */ jsxs(
7871
+ Button,
7872
+ {
7873
+ variant: "outline",
7874
+ size: "icon",
7875
+ className: "size-7 [&_svg]:size-4",
7876
+ onClick: goToNext,
7877
+ children: [
7878
+ /* @__PURE__ */ jsx(ChevronRight, {}),
7879
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Next" })
7880
+ ]
7881
+ }
7882
+ )
7883
+ ] })
7884
+ ] })
7885
+ ] }),
7886
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1.5 sm:flex-row sm:justify-between", children: [
7887
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-1.5", children: [
7888
+ showViewSwitcher && /* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-1 rounded-full border border-border px-1 py-1", children: VIEW_CONFIG.map((config, index) => {
7889
+ const Icon2 = config.icon;
7890
+ const isFirst = index === 0;
7891
+ const isLast = index === VIEW_CONFIG.length - 1;
7892
+ const isActive = view === config.view;
7893
+ return /* @__PURE__ */ jsx(
7894
+ Button,
7895
+ {
7896
+ "aria-label": config.label,
7897
+ size: "icon",
7898
+ variant: isActive ? "default" : "ghost",
7899
+ className: cn(
7900
+ "size-8 border-0 [&_svg]:size-4",
7901
+ isFirst && "rounded-l-full rounded-r-sm",
7902
+ isLast && "rounded-r-full rounded-l-sm",
7903
+ !isFirst && !isLast && "rounded-sm"
7904
+ ),
7905
+ onClick: () => setView(config.view),
7906
+ children: /* @__PURE__ */ jsx(Icon2, { strokeWidth: 1.8 })
7907
+ },
7908
+ config.view
7909
+ );
7910
+ }) }),
7911
+ showUserFilter && users.length > 0 && /* @__PURE__ */ jsxs(
7912
+ Select,
7913
+ {
7914
+ value: selectedUserId || "all",
7915
+ onValueChange: (value) => setSelectedUserId(value === "all" ? null : value),
7916
+ children: [
7917
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "flex-1 md:w-48", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
7918
+ /* @__PURE__ */ jsxs(SelectContent, { align: "end", children: [
7919
+ /* @__PURE__ */ jsx(SelectItem, { value: "all", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
7920
+ /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
7921
+ users.slice(0, 2).map((user) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-background", children: [
7922
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.picturePath, alt: user.name }),
7923
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[10px]", children: getInitials(user.name) })
7924
+ ] }, user.id)),
7925
+ users.length > 2 && /* @__PURE__ */ jsxs("div", { className: "flex size-6 items-center justify-center rounded-full border-2 border-background bg-muted text-[10px] font-medium", children: [
7926
+ "+",
7927
+ users.length - 2
7928
+ ] })
7929
+ ] }),
7930
+ "All"
7931
+ ] }) }),
7932
+ users.map((user) => /* @__PURE__ */ jsx(SelectItem, { value: user.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7933
+ /* @__PURE__ */ jsxs(Avatar, { className: "size-6", children: [
7934
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.picturePath, alt: user.name }),
7935
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[10px]", children: getInitials(user.name) })
7936
+ ] }),
7937
+ /* @__PURE__ */ jsx("p", { className: "truncate", children: user.name })
7938
+ ] }) }, user.id))
7939
+ ] })
7940
+ ]
7941
+ }
7942
+ )
7943
+ ] }),
7944
+ showAddButton && /* @__PURE__ */ jsxs(Button, { onClick: onAddClick, className: "w-full sm:w-auto", children: [
7945
+ /* @__PURE__ */ jsx(Plus, {}),
7946
+ "Add Event"
7947
+ ] })
7948
+ ] })
7949
+ ]
7950
+ }
7951
+ );
7952
+ }
7953
+ function CalendarHeaderCompact({
7954
+ className,
7955
+ showAddButton = true,
7956
+ onAddClick
7957
+ }) {
7958
+ const {
7959
+ selectedDate,
7960
+ setSelectedDate,
7961
+ view,
7962
+ setView,
7963
+ goToPrevious,
7964
+ goToNext
7965
+ } = useEventCalendar();
7966
+ const filteredEvents = useFilteredEvents();
7967
+ const eventCount = filteredEvents.length;
7968
+ const today = /* @__PURE__ */ new Date();
7969
+ const handleTodayClick = () => {
7970
+ setSelectedDate(/* @__PURE__ */ new Date());
7971
+ };
7972
+ return /* @__PURE__ */ jsxs(
7973
+ "div",
7974
+ {
7975
+ className: cn(
7976
+ "flex items-center justify-between border-b border-border p-3",
7977
+ className
7978
+ ),
7979
+ children: [
7980
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7981
+ /* @__PURE__ */ jsxs(
7982
+ "button",
7983
+ {
7984
+ type: "button",
7985
+ onClick: handleTodayClick,
7986
+ className: "flex size-10 flex-col items-start overflow-hidden rounded border focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
7987
+ children: [
7988
+ /* @__PURE__ */ jsx("p", { className: "flex h-4 w-full items-center justify-center bg-primary text-center text-[8px] font-semibold text-primary-foreground", children: format(today, "MMM").toUpperCase() }),
7989
+ /* @__PURE__ */ jsx("p", { className: "flex w-full flex-1 items-center justify-center text-sm font-bold", children: today.getDate() })
7990
+ ]
7991
+ }
7992
+ ),
7993
+ /* @__PURE__ */ jsxs("div", { children: [
7994
+ /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold", children: format(selectedDate, "MMM yyyy") }),
7995
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
7996
+ eventCount,
7997
+ " events"
7998
+ ] })
7999
+ ] })
8000
+ ] }),
8001
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8002
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-8", onClick: goToPrevious, children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" }) }),
8003
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-8", onClick: goToNext, children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" }) }),
8004
+ /* @__PURE__ */ jsxs("div", { className: "ml-2 inline-flex items-center gap-0.5 rounded-full border border-border px-0.5 py-0.5", children: [
8005
+ /* @__PURE__ */ jsx(
8006
+ Button,
8007
+ {
8008
+ size: "icon",
8009
+ variant: view === "day" ? "default" : "ghost",
8010
+ className: "size-6 rounded-l-full rounded-r-sm border-0 [&_svg]:size-3",
8011
+ onClick: () => setView("day"),
8012
+ children: /* @__PURE__ */ jsx(List, { strokeWidth: 1.8 })
8013
+ }
8014
+ ),
8015
+ /* @__PURE__ */ jsx(
8016
+ Button,
8017
+ {
8018
+ size: "icon",
8019
+ variant: view === "week" ? "default" : "ghost",
8020
+ className: "size-6 rounded-sm border-0 [&_svg]:size-3",
8021
+ onClick: () => setView("week"),
8022
+ children: /* @__PURE__ */ jsx(Columns, { strokeWidth: 1.8 })
8023
+ }
8024
+ ),
8025
+ /* @__PURE__ */ jsx(
8026
+ Button,
8027
+ {
8028
+ size: "icon",
8029
+ variant: view === "month" ? "default" : "ghost",
8030
+ className: "size-6 rounded-r-full rounded-l-sm border-0 [&_svg]:size-3",
8031
+ onClick: () => setView("month"),
8032
+ children: /* @__PURE__ */ jsx(Grid2x2, { strokeWidth: 1.8 })
8033
+ }
8034
+ )
8035
+ ] }),
8036
+ showAddButton && /* @__PURE__ */ jsx(Button, { size: "sm", onClick: onAddClick, className: "ml-2 size-8 p-0", children: /* @__PURE__ */ jsx(Plus, { className: "size-4" }) })
8037
+ ] })
8038
+ ]
8039
+ }
8040
+ );
8041
+ }
8042
+ var EVENT_COLORS2 = [
8043
+ { value: "blue", label: "Blue", className: "bg-blue-500" },
8044
+ { value: "green", label: "Green", className: "bg-green-500" },
8045
+ { value: "red", label: "Red", className: "bg-red-500" },
8046
+ { value: "yellow", label: "Yellow", className: "bg-yellow-500" },
8047
+ { value: "purple", label: "Purple", className: "bg-purple-500" },
8048
+ { value: "orange", label: "Orange", className: "bg-primary" }
8049
+ ];
8050
+ function EventDialog({
8051
+ open,
8052
+ onOpenChange,
8053
+ mode = "add",
8054
+ event,
8055
+ defaultDate = /* @__PURE__ */ new Date(),
8056
+ defaultUserId
8057
+ }) {
8058
+ const { addEvent, updateEvent, deleteEvent, users } = useEventCalendar();
8059
+ const [title, setTitle] = React14.useState("");
8060
+ const [description, setDescription] = React14.useState("");
8061
+ const [startDate, setStartDate] = React14.useState("");
8062
+ const [startTime, setStartTime] = React14.useState("");
8063
+ const [endDate, setEndDate] = React14.useState("");
8064
+ const [endTime, setEndTime] = React14.useState("");
8065
+ const [color, setColor] = React14.useState("blue");
8066
+ const [userId, setUserId] = React14.useState("");
8067
+ const [isSubmitting, setIsSubmitting] = React14.useState(false);
8068
+ React14.useEffect(() => {
8069
+ if (open) {
8070
+ if (mode === "edit" && event) {
8071
+ const start = parseISO(event.startDate);
8072
+ const end = parseISO(event.endDate);
8073
+ setTitle(event.title);
8074
+ setDescription(event.description || "");
8075
+ setStartDate(format(start, "yyyy-MM-dd"));
8076
+ setStartTime(format(start, "HH:mm"));
8077
+ setEndDate(format(end, "yyyy-MM-dd"));
8078
+ setEndTime(format(end, "HH:mm"));
8079
+ setColor(event.color);
8080
+ setUserId(event.user.id);
8081
+ } else {
8082
+ const start = defaultDate;
8083
+ const end = setMinutes(setHours(defaultDate, defaultDate.getHours() + 1), 0);
8084
+ setTitle("");
8085
+ setDescription("");
8086
+ setStartDate(format(start, "yyyy-MM-dd"));
8087
+ setStartTime(format(start, "HH:mm"));
8088
+ setEndDate(format(end, "yyyy-MM-dd"));
8089
+ setEndTime(format(end, "HH:mm"));
8090
+ setColor("blue");
8091
+ setUserId(defaultUserId || users[0]?.id || "");
8092
+ }
8093
+ }
8094
+ }, [open, mode, event, defaultDate, defaultUserId, users]);
8095
+ const handleSubmit = async (e) => {
8096
+ e.preventDefault();
8097
+ setIsSubmitting(true);
8098
+ try {
8099
+ const [startYear, startMonth, startDay] = startDate.split("-").map(Number);
8100
+ const [startHour, startMinute] = startTime.split(":").map(Number);
8101
+ const [endYear, endMonth, endDay] = endDate.split("-").map(Number);
8102
+ const [endHour, endMinute] = endTime.split(":").map(Number);
8103
+ const startDateTime = new Date(startYear, startMonth - 1, startDay, startHour, startMinute);
8104
+ const endDateTime = new Date(endYear, endMonth - 1, endDay, endHour, endMinute);
8105
+ const selectedUser = users.find((u) => u.id === userId);
8106
+ if (mode === "edit" && event) {
8107
+ const updatedEvent = {
8108
+ ...event,
8109
+ title,
8110
+ description,
8111
+ startDate: startDateTime.toISOString(),
8112
+ endDate: endDateTime.toISOString(),
8113
+ color,
8114
+ user: {
8115
+ id: userId,
8116
+ name: selectedUser?.name || "Unknown"
8117
+ }
8118
+ };
8119
+ updateEvent(updatedEvent);
8120
+ } else {
8121
+ const newEvent = {
8122
+ id: generateEventId(),
8123
+ title,
8124
+ description,
8125
+ startDate: startDateTime.toISOString(),
8126
+ endDate: endDateTime.toISOString(),
8127
+ color,
8128
+ user: {
8129
+ id: userId,
8130
+ name: selectedUser?.name || "Unknown"
8131
+ }
8132
+ };
8133
+ addEvent(newEvent);
8134
+ }
8135
+ onOpenChange(false);
8136
+ } catch (error) {
8137
+ console.error("Failed to save event:", error);
8138
+ } finally {
8139
+ setIsSubmitting(false);
8140
+ }
8141
+ };
8142
+ const handleDelete = () => {
8143
+ if (event) {
8144
+ deleteEvent(event.id);
8145
+ onOpenChange(false);
8146
+ }
8147
+ };
8148
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogContent, { className: "sm:max-w-[500px]", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
8149
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
8150
+ /* @__PURE__ */ jsx(DialogTitle, { children: mode === "edit" ? "Edit Event" : "Add Event" }),
8151
+ /* @__PURE__ */ jsx(DialogDescription, { children: mode === "edit" ? "Make changes to your event below." : "Fill in the details for your new event." })
8152
+ ] }),
8153
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 py-4", children: [
8154
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8155
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "title", children: "Title" }),
8156
+ /* @__PURE__ */ jsx(
8157
+ Input,
8158
+ {
8159
+ id: "title",
8160
+ value: title,
8161
+ onChange: (e) => setTitle(e.target.value),
8162
+ placeholder: "Event title",
8163
+ required: true
8164
+ }
8165
+ )
8166
+ ] }),
8167
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8168
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "description", children: "Description" }),
8169
+ /* @__PURE__ */ jsx(
8170
+ Textarea,
8171
+ {
8172
+ id: "description",
8173
+ value: description,
8174
+ onChange: (e) => setDescription(e.target.value),
8175
+ placeholder: "Event description (optional)",
8176
+ rows: 3
8177
+ }
8178
+ )
8179
+ ] }),
8180
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8181
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8182
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "startDate", children: "Start Date" }),
8183
+ /* @__PURE__ */ jsx(
8184
+ Input,
8185
+ {
8186
+ id: "startDate",
8187
+ type: "date",
8188
+ value: startDate,
8189
+ onChange: (e) => setStartDate(e.target.value),
8190
+ required: true
8191
+ }
8192
+ )
8193
+ ] }),
8194
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8195
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "startTime", children: "Start Time" }),
8196
+ /* @__PURE__ */ jsx(
8197
+ Input,
8198
+ {
8199
+ id: "startTime",
8200
+ type: "time",
8201
+ value: startTime,
8202
+ onChange: (e) => setStartTime(e.target.value),
8203
+ required: true
8204
+ }
8205
+ )
8206
+ ] })
8207
+ ] }),
8208
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8209
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8210
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "endDate", children: "End Date" }),
8211
+ /* @__PURE__ */ jsx(
8212
+ Input,
8213
+ {
8214
+ id: "endDate",
8215
+ type: "date",
8216
+ value: endDate,
8217
+ onChange: (e) => setEndDate(e.target.value),
8218
+ required: true
8219
+ }
8220
+ )
8221
+ ] }),
8222
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8223
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "endTime", children: "End Time" }),
8224
+ /* @__PURE__ */ jsx(
8225
+ Input,
8226
+ {
8227
+ id: "endTime",
8228
+ type: "time",
8229
+ value: endTime,
8230
+ onChange: (e) => setEndTime(e.target.value),
8231
+ required: true
8232
+ }
8233
+ )
8234
+ ] })
8235
+ ] }),
8236
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8237
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8238
+ /* @__PURE__ */ jsx(Label2, { children: "Color" }),
8239
+ /* @__PURE__ */ jsxs(Select, { value: color, onValueChange: (v) => setColor(v), children: [
8240
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8241
+ /* @__PURE__ */ jsx(
8242
+ "span",
8243
+ {
8244
+ className: cn(
8245
+ "size-3 rounded-full",
8246
+ EVENT_COLORS2.find((c) => c.value === color)?.className
8247
+ )
8248
+ }
8249
+ ),
8250
+ EVENT_COLORS2.find((c) => c.value === color)?.label
8251
+ ] }) }) }),
8252
+ /* @__PURE__ */ jsx(SelectContent, { children: EVENT_COLORS2.map((c) => /* @__PURE__ */ jsx(SelectItem, { value: c.value, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8253
+ /* @__PURE__ */ jsx("span", { className: cn("size-3 rounded-full", c.className) }),
8254
+ c.label
8255
+ ] }) }, c.value)) })
8256
+ ] })
8257
+ ] }),
8258
+ users.length > 0 && /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8259
+ /* @__PURE__ */ jsx(Label2, { children: "Assignee" }),
8260
+ /* @__PURE__ */ jsxs(Select, { value: userId, onValueChange: setUserId, children: [
8261
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select user" }) }),
8262
+ /* @__PURE__ */ jsx(SelectContent, { children: users.map((user) => /* @__PURE__ */ jsx(SelectItem, { value: user.id, children: user.name }, user.id)) })
8263
+ ] })
8264
+ ] })
8265
+ ] })
8266
+ ] }),
8267
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "flex-row justify-between gap-2", children: [
8268
+ mode === "edit" ? /* @__PURE__ */ jsx(
8269
+ Button,
8270
+ {
8271
+ type: "button",
8272
+ variant: "destructive",
8273
+ onClick: handleDelete,
8274
+ disabled: isSubmitting,
8275
+ children: "Delete"
8276
+ }
8277
+ ) : /* @__PURE__ */ jsx("div", {}),
8278
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
8279
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
8280
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting || !title.trim(), children: isSubmitting ? "Saving..." : mode === "edit" ? "Save Changes" : "Add Event" })
8281
+ ] })
8282
+ ] })
8283
+ ] }) }) });
8284
+ }
8285
+ function QuickAddEvent({
8286
+ date,
8287
+ onAdd,
8288
+ onOpenDialog,
8289
+ onClose
8290
+ }) {
8291
+ const [title, setTitle] = React14.useState("");
8292
+ const { users } = useEventCalendar();
8293
+ const handleSubmit = (e) => {
8294
+ e.preventDefault();
8295
+ if (!title.trim()) return;
8296
+ const end = setMinutes(setHours(date, date.getHours() + 1), 0);
8297
+ onAdd({
8298
+ title,
8299
+ description: "",
8300
+ startDate: date.toISOString(),
8301
+ endDate: end.toISOString(),
8302
+ color: "blue",
8303
+ user: {
8304
+ id: users[0]?.id || "",
8305
+ name: users[0]?.name || "Unknown"
8306
+ }
8307
+ });
8308
+ onClose();
8309
+ };
8310
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-2 p-3", children: [
8311
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: format(date, "EEE, MMM d, h:mm a") }),
8312
+ /* @__PURE__ */ jsx(
8313
+ Input,
8314
+ {
8315
+ value: title,
8316
+ onChange: (e) => setTitle(e.target.value),
8317
+ placeholder: "Add title",
8318
+ className: "h-8",
8319
+ autoFocus: true
8320
+ }
8321
+ ),
8322
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
8323
+ /* @__PURE__ */ jsx(Button, { type: "submit", size: "sm", disabled: !title.trim(), children: "Add" }),
8324
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onOpenDialog, children: "More options" })
8325
+ ] })
8326
+ ] });
8327
+ }
8328
+ function ChangeBadgeVariantInput() {
8329
+ const { badgeVariant, setBadgeVariant } = useEventCalendar();
8330
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8331
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Change badge variant" }),
8332
+ /* @__PURE__ */ jsxs(
8333
+ Select,
8334
+ {
8335
+ value: badgeVariant,
8336
+ onValueChange: (value) => setBadgeVariant(value),
8337
+ children: [
8338
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-48", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8339
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
8340
+ /* @__PURE__ */ jsx(SelectItem, { value: "dot", children: "Dot" }),
8341
+ /* @__PURE__ */ jsx(SelectItem, { value: "colored", children: "Colored" }),
8342
+ /* @__PURE__ */ jsx(SelectItem, { value: "mixed", children: "Mixed" })
8343
+ ] })
8344
+ ]
8345
+ }
8346
+ )
8347
+ ] });
8348
+ }
8349
+ var HOUR_OPTIONS = Array.from({ length: 25 }, (_, i) => {
8350
+ if (i === 0) return { value: "0", label: "12 AM" };
8351
+ if (i === 12) return { value: "12", label: "12 PM" };
8352
+ if (i === 24) return { value: "24", label: "12 AM (next)" };
8353
+ if (i < 12) return { value: String(i), label: `${i} AM` };
8354
+ return { value: String(i), label: `${i - 12} PM` };
8355
+ });
8356
+ function ChangeVisibleHoursInput() {
8357
+ const { visibleHours, setVisibleHours } = useEventCalendar();
8358
+ const [from, setFrom] = React14.useState(visibleHours.from);
8359
+ const [to, setTo] = React14.useState(visibleHours.to);
8360
+ const handleApply = () => {
8361
+ const toHour = to === 0 ? 24 : to;
8362
+ setVisibleHours({ from, to: toHour });
8363
+ };
8364
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8365
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8366
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Change visible hours" }),
8367
+ /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 100, children: /* @__PURE__ */ jsxs(Tooltip2, { children: [
8368
+ /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(Info, { className: "size-3" }) }),
8369
+ /* @__PURE__ */ jsx(TooltipContent, { className: "max-w-80 text-center", children: /* @__PURE__ */ jsx("p", { children: "If an event falls outside the specified visible hours, the visible hours will automatically adjust to include that event." }) })
8370
+ ] }) })
8371
+ ] }),
8372
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
8373
+ /* @__PURE__ */ jsx("p", { children: "From" }),
8374
+ /* @__PURE__ */ jsxs(Select, { value: String(from), onValueChange: (v) => setFrom(Number(v)), children: [
8375
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-28", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8376
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS.slice(0, 24).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8377
+ ] }),
8378
+ /* @__PURE__ */ jsx("p", { children: "To" }),
8379
+ /* @__PURE__ */ jsxs(Select, { value: String(to), onValueChange: (v) => setTo(Number(v)), children: [
8380
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-28", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8381
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS.slice(1).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8382
+ ] })
8383
+ ] }),
8384
+ /* @__PURE__ */ jsx(Button, { className: "mt-4 w-fit", onClick: handleApply, children: "Apply" })
8385
+ ] });
8386
+ }
8387
+ var DAYS_OF_WEEK = [
8388
+ { index: 0, name: "Sunday" },
8389
+ { index: 1, name: "Monday" },
8390
+ { index: 2, name: "Tuesday" },
8391
+ { index: 3, name: "Wednesday" },
8392
+ { index: 4, name: "Thursday" },
8393
+ { index: 5, name: "Friday" },
8394
+ { index: 6, name: "Saturday" }
8395
+ ];
8396
+ var HOUR_OPTIONS2 = Array.from({ length: 25 }, (_, i) => {
8397
+ if (i === 0) return { value: "0", label: "12 AM" };
8398
+ if (i === 12) return { value: "12", label: "12 PM" };
8399
+ if (i === 24) return { value: "24", label: "12 AM (next)" };
8400
+ if (i < 12) return { value: String(i), label: `${i} AM` };
8401
+ return { value: String(i), label: `${i - 12} PM` };
8402
+ });
8403
+ function ChangeWorkingHoursInput() {
8404
+ const { workingHours, setWorkingHours } = useEventCalendar();
8405
+ const [localWorkingHours, setLocalWorkingHours] = React14.useState({
8406
+ ...workingHours
8407
+ });
8408
+ const handleToggleDay = (dayId) => {
8409
+ setLocalWorkingHours((prev) => ({
8410
+ ...prev,
8411
+ [dayId]: prev[dayId].from > 0 || prev[dayId].to > 0 ? { from: 0, to: 0 } : { from: 9, to: 17 }
8412
+ }));
8413
+ };
8414
+ const handleTimeChange = (dayId, timeType, value) => {
8415
+ const hour = Number(value);
8416
+ setLocalWorkingHours((prev) => {
8417
+ const updatedDay = { ...prev[dayId], [timeType]: hour };
8418
+ if (timeType === "to" && hour === 0 && updatedDay.from === 0) {
8419
+ updatedDay.to = 24;
8420
+ }
8421
+ return { ...prev, [dayId]: updatedDay };
8422
+ });
8423
+ };
8424
+ const handleSave = () => {
8425
+ const updatedWorkingHours = { ...localWorkingHours };
8426
+ for (const dayId in updatedWorkingHours) {
8427
+ const day = updatedWorkingHours[parseInt(dayId)];
8428
+ const isDayActive = localWorkingHours[parseInt(dayId)].from > 0 || localWorkingHours[parseInt(dayId)].to > 0;
8429
+ if (isDayActive) {
8430
+ if (day.from === 0 && day.to === 0) {
8431
+ updatedWorkingHours[dayId] = { from: 0, to: 24 };
8432
+ } else if (day.to === 0 && day.from > 0) {
8433
+ updatedWorkingHours[dayId] = { ...day, to: 24 };
8434
+ }
8435
+ } else {
8436
+ updatedWorkingHours[dayId] = { from: 0, to: 0 };
8437
+ }
8438
+ }
8439
+ setWorkingHours(updatedWorkingHours);
8440
+ };
8441
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8442
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8443
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Change working hours" }),
8444
+ /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 100, children: /* @__PURE__ */ jsxs(Tooltip2, { children: [
8445
+ /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(Info, { className: "size-3" }) }),
8446
+ /* @__PURE__ */ jsx(TooltipContent, { className: "max-w-80 text-center", children: /* @__PURE__ */ jsx("p", { children: "This will apply a dashed background to the hour cells that fall outside the working hours \u2014 only for week and day views." }) })
8447
+ ] }) })
8448
+ ] }),
8449
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: DAYS_OF_WEEK.map((day) => {
8450
+ const isDayActive = localWorkingHours[day.index].from > 0 || localWorkingHours[day.index].to > 0;
8451
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-4", children: [
8452
+ /* @__PURE__ */ jsxs("div", { className: "flex w-32 items-center gap-2 sm:w-36", children: [
8453
+ /* @__PURE__ */ jsx(
8454
+ Switch,
8455
+ {
8456
+ checked: isDayActive,
8457
+ onCheckedChange: () => handleToggleDay(day.index)
8458
+ }
8459
+ ),
8460
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: day.name.slice(0, 3) })
8461
+ ] }),
8462
+ isDayActive ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
8463
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8464
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "From" }),
8465
+ /* @__PURE__ */ jsxs(
8466
+ Select,
8467
+ {
8468
+ value: String(localWorkingHours[day.index].from),
8469
+ onValueChange: (v) => handleTimeChange(day.index, "from", v),
8470
+ children: [
8471
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-24", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8472
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS2.slice(0, 24).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8473
+ ]
8474
+ }
8475
+ )
8476
+ ] }),
8477
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8478
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "To" }),
8479
+ /* @__PURE__ */ jsxs(
8480
+ Select,
8481
+ {
8482
+ value: String(localWorkingHours[day.index].to),
8483
+ onValueChange: (v) => handleTimeChange(day.index, "to", v),
8484
+ children: [
8485
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-24", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8486
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS2.slice(1).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8487
+ ]
8488
+ }
8489
+ )
8490
+ ] })
8491
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
8492
+ /* @__PURE__ */ jsx(Moon, { className: "size-4" }),
8493
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Closed" })
8494
+ ] })
8495
+ ] }, day.index);
8496
+ }) }),
8497
+ /* @__PURE__ */ jsx(Button, { className: "mt-4 w-fit", onClick: handleSave, children: "Apply" })
8498
+ ] });
8499
+ }
8500
+ function CalendarSettingsPanel({
8501
+ className,
8502
+ showBadgeVariant = true,
8503
+ showVisibleHours = true,
8504
+ showWorkingHours = true
8505
+ }) {
8506
+ return /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: cn("relative z-10 bg-background", className), children: /* @__PURE__ */ jsxs(AccordionItem, { value: "settings", className: "border-none", children: [
8507
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "flex-none gap-2 py-0 hover:no-underline", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8508
+ /* @__PURE__ */ jsx(Settings, { className: "size-4" }),
8509
+ /* @__PURE__ */ jsx("p", { className: "text-base font-semibold", children: "Calendar settings" })
8510
+ ] }) }),
8511
+ /* @__PURE__ */ jsx(AccordionContent, { children: /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col gap-6", children: [
8512
+ showBadgeVariant && /* @__PURE__ */ jsx(ChangeBadgeVariantInput, {}),
8513
+ showVisibleHours && /* @__PURE__ */ jsx(ChangeVisibleHoursInput, {}),
8514
+ showWorkingHours && /* @__PURE__ */ jsx(ChangeWorkingHoursInput, {})
8515
+ ] }) })
8516
+ ] }) });
8517
+ }
8518
+ function useMediaQuery(query) {
8519
+ const [matches, setMatches] = React14.useState(false);
8520
+ React14.useEffect(() => {
8521
+ const media = window.matchMedia(query);
8522
+ setMatches(media.matches);
8523
+ const listener = (event) => {
8524
+ setMatches(event.matches);
8525
+ };
8526
+ media.addEventListener("change", listener);
8527
+ return () => media.removeEventListener("change", listener);
8528
+ }, [query]);
8529
+ return matches;
8530
+ }
8531
+ function BigCalendar({
8532
+ className,
8533
+ compact = "auto",
8534
+ bordered = true,
8535
+ showHeader = true,
8536
+ showAddButton = true,
8537
+ showSettings = true,
8538
+ enableDragDrop = true,
8539
+ weekStartsOn = 0,
8540
+ maxEventsPerDay = 3,
8541
+ config,
8542
+ ...providerProps
8543
+ }) {
8544
+ return /* @__PURE__ */ jsx(EventCalendarProvider, { ...providerProps, children: /* @__PURE__ */ jsx(DragProvider, { children: /* @__PURE__ */ jsx(
8545
+ BigCalendarInner,
8546
+ {
8547
+ className,
8548
+ compact,
8549
+ bordered,
8550
+ showHeader,
8551
+ showAddButton,
8552
+ showSettings,
8553
+ enableDragDrop,
8554
+ weekStartsOn,
8555
+ maxEventsPerDay,
8556
+ config
8557
+ }
8558
+ ) }) });
8559
+ }
8560
+ function BigCalendarInner({
8561
+ className,
8562
+ compact,
8563
+ bordered,
8564
+ showHeader,
8565
+ showAddButton,
8566
+ showSettings,
8567
+ enableDragDrop,
8568
+ weekStartsOn,
8569
+ maxEventsPerDay
8570
+ }) {
8571
+ const { view, setView } = useEventCalendar();
8572
+ const [dialogOpen, setDialogOpen] = React14.useState(false);
8573
+ const [selectedEvent, setSelectedEvent] = React14.useState(null);
8574
+ const [dialogMode, setDialogMode] = React14.useState("add");
8575
+ const [defaultDate, setDefaultDate] = React14.useState(/* @__PURE__ */ new Date());
8576
+ const isMobile = useMediaQuery("(max-width: 768px)");
8577
+ const isCompact = compact === "auto" ? isMobile : compact;
8578
+ const handleAddClick = () => {
8579
+ setSelectedEvent(null);
8580
+ setDialogMode("add");
8581
+ setDefaultDate(/* @__PURE__ */ new Date());
8582
+ setDialogOpen(true);
8583
+ };
8584
+ const handleEventClick = (event) => {
8585
+ setSelectedEvent(event);
8586
+ setDialogMode("edit");
8587
+ setDialogOpen(true);
8588
+ };
8589
+ const handleDateClick = (date) => {
8590
+ setDefaultDate(date);
8591
+ };
8592
+ const handleMoreClick = (date, events) => {
8593
+ setDefaultDate(date);
8594
+ setView("day");
8595
+ };
8596
+ const handleTimeClick = (date, hour, minute) => {
8597
+ setSelectedEvent(null);
8598
+ setDialogMode("add");
8599
+ const clickedDate = new Date(date);
8600
+ clickedDate.setHours(hour, minute, 0, 0);
8601
+ setDefaultDate(clickedDate);
8602
+ setDialogOpen(true);
8603
+ };
8604
+ const Wrapper = bordered ? Card : "div";
8605
+ const Content14 = bordered ? CardContent : "div";
8606
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
8607
+ /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4 relative", className), children: [
8608
+ /* @__PURE__ */ jsxs(
8609
+ Wrapper,
8610
+ {
8611
+ className: cn(
8612
+ "flex min-h-[600px] flex-col overflow-hidden rounded-sm",
8613
+ !bordered && "border border-border bg-card"
8614
+ ),
8615
+ children: [
8616
+ showHeader && (isCompact ? /* @__PURE__ */ jsx(
8617
+ CalendarHeaderCompact,
8618
+ {
8619
+ showAddButton,
8620
+ onAddClick: handleAddClick
8621
+ }
8622
+ ) : /* @__PURE__ */ jsx(
8623
+ CalendarHeader,
8624
+ {
8625
+ showAddButton,
8626
+ onAddClick: handleAddClick
8627
+ }
8628
+ )),
8629
+ /* @__PURE__ */ jsx(Content14, { className: cn("flex-1 overflow-hidden", bordered ? "p-0" : ""), children: /* @__PURE__ */ jsx(
8630
+ CalendarView,
8631
+ {
8632
+ view,
8633
+ weekStartsOn,
8634
+ maxEventsPerDay,
8635
+ onEventClick: handleEventClick,
8636
+ onDateClick: handleDateClick,
8637
+ onMoreClick: handleMoreClick,
8638
+ onTimeClick: handleTimeClick
8639
+ }
8640
+ ) })
8641
+ ]
8642
+ }
8643
+ ),
8644
+ showSettings && /* @__PURE__ */ jsx(CalendarSettingsPanel, {})
8645
+ ] }),
8646
+ /* @__PURE__ */ jsx(
8647
+ EventDialog,
8648
+ {
8649
+ open: dialogOpen,
8650
+ onOpenChange: setDialogOpen,
8651
+ mode: dialogMode,
8652
+ event: selectedEvent,
8653
+ defaultDate
8654
+ }
8655
+ )
8656
+ ] });
8657
+ }
8658
+ function CalendarView({
8659
+ view,
8660
+ weekStartsOn,
8661
+ maxEventsPerDay,
8662
+ onEventClick,
8663
+ onDateClick,
8664
+ onMoreClick,
8665
+ onTimeClick
8666
+ }) {
8667
+ switch (view) {
8668
+ case "month":
8669
+ return /* @__PURE__ */ jsx(
8670
+ MonthView,
8671
+ {
8672
+ className: "h-full",
8673
+ weekStartsOn,
8674
+ maxEventsPerDay,
8675
+ onEventClick,
8676
+ onDateClick,
8677
+ onMoreClick
8678
+ }
8679
+ );
8680
+ case "week":
8681
+ return /* @__PURE__ */ jsx(
8682
+ WeekView,
8683
+ {
8684
+ className: "h-full",
8685
+ weekStartsOn,
8686
+ onEventClick,
8687
+ onDateClick,
8688
+ onTimeClick
8689
+ }
8690
+ );
8691
+ case "day":
8692
+ return /* @__PURE__ */ jsx(
8693
+ DayView,
8694
+ {
8695
+ className: "h-full",
8696
+ onEventClick,
8697
+ onTimeClick
8698
+ }
8699
+ );
8700
+ case "year":
8701
+ return /* @__PURE__ */ jsx(
8702
+ YearView,
8703
+ {
8704
+ className: "h-full",
8705
+ weekStartsOn,
8706
+ onDateClick
8707
+ }
8708
+ );
8709
+ case "agenda":
8710
+ return /* @__PURE__ */ jsx(
8711
+ AgendaView,
8712
+ {
8713
+ className: "h-full",
8714
+ onEventClick,
8715
+ onDateClick
8716
+ }
8717
+ );
8718
+ default:
8719
+ return null;
8720
+ }
8721
+ }
5430
8722
 
5431
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Item5 as Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label2 as Label, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PlayerCanvas, PlayerCanvasActionButton, PlayerCanvasControls, PlayerCanvasDivider, PlayerCanvasInfo, PlayerCanvasLabel, PlayerCanvasPlayButton, PlayerCanvasProgress, PlayerCanvasSkipButton, PlayerCanvasTitle, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Section, SectionContent, SectionDescription, SectionFooter, SectionHeader, SectionTitle, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolBarCanvas, ToolBarCanvasButton, ToolBarCanvasDivider, ToolBarCanvasGroup, Tooltip2 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonGroupVariants, buttonVariants, cardVariants, navigationMenuTriggerStyle, playerCanvasPlayButtonVariants, playerCanvasSkipButtonVariants, sectionVariants, toggleVariants, toolBarCanvasButtonVariants, useFormField, useIsMobile, useSidebar };
8723
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgendaView, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, BADGE_VARIANT_LABELS, Badge, BigCalendar, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarContext, CalendarDayButton, CalendarHeader, CalendarHeaderCompact, CalendarSettingsPanel, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChangeBadgeVariantInput, ChangeVisibleHoursInput, ChangeWorkingHoursInput, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_VISIBLE_HOURS, DEFAULT_WORKING_HOURS, DateBadge, DayView, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DragContext, DragProvider, DraggableEvent, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DroppableZone, EVENT_COLORS, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EventBadge, EventCalendarProvider, EventDialog, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Item6 as Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label2 as Label, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MonthView, MoreEvents, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavMain, NavProjects, NavSecondary, NavUser, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PlayerCanvas, PlayerCanvasActionButton, PlayerCanvasControls, PlayerCanvasDivider, PlayerCanvasInfo, PlayerCanvasLabel, PlayerCanvasPlayButton, PlayerCanvasProgress, PlayerCanvasSkipButton, PlayerCanvasTitle, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, QuickAddEvent, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, SearchForm, SearchTrigger, Section, SectionContent, SectionDescription, SectionFooter, SectionHeader, SectionTitle, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiteHeader, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TimeIndicator, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolBarCanvas, ToolBarCanvasButton, ToolBarCanvasDivider, ToolBarCanvasGroup, Tooltip2 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatarsDropdown, VIEW_LABELS, WeekView, YearView, badgeVariants, buttonGroupVariants, buttonVariants, calculateDropDates, calculateMonthEventPositions, cardVariants, createDefaultEvent, formatDateRange, formatTime, generateEventId, getCalendarCells, getCurrentEvents, getDayHours, getEventBlockStyle, getEventDuration, getEventDurationMinutes, getEventsCount, getEventsForDate, getEventsInRange, getHeaderLabel, getMonthCellEvents, getMonthDays, getTimeHeight, getTimePosition, getViewDateRange, getVisibleHours, getWeekDayNames, getWeekDays, getYearMonths, groupEvents, isMultiDayEvent, isWorkingHour, navigateDate, navigationMenuTriggerStyle, playerCanvasPlayButtonVariants, playerCanvasSkipButtonVariants, rangeText, sectionVariants, snapToInterval, sortEvents, splitEventsByDuration, toggleVariants, toolBarCanvasButtonVariants, useDrag, useDraggable, useDroppable, useEventCalendar, useEventsInRange, useFilteredEvents, useFormField, useIsMobile, useSearchShortcut, useSidebar };
5432
8724
  //# sourceMappingURL=index.js.map
5433
8725
  //# sourceMappingURL=index.js.map