@j3m-quantum/ui 1.0.0 → 1.3.1

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 React15 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] = React15.useState(void 0);
49
+ React15.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 = React15.forwardRef(
89
91
  ({ className, variant, size, asChild = false, ...props }, ref) => {
90
92
  const Comp = asChild ? Slot : "button";
91
93
  return /* @__PURE__ */ jsx(
@@ -193,7 +195,7 @@ function Input({ className, type, ...props }) {
193
195
  type,
194
196
  "data-slot": "input",
195
197
  className: cn(
196
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
198
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-4 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
197
199
  "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
198
200
  "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
199
201
  className
@@ -449,7 +451,7 @@ function Slider({
449
451
  max = 100,
450
452
  ...props
451
453
  }) {
452
- const _values = React7.useMemo(
454
+ const _values = React15.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 = React15.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 = React15.useContext(ToggleGroupContext);
776
778
  return /* @__PURE__ */ jsx(
777
779
  ToggleGroupPrimitive.Item,
778
780
  {
@@ -794,6 +796,125 @@ function ToggleGroupItem({
794
796
  }
795
797
  );
796
798
  }
799
+ function ThemeSwitch({
800
+ checked,
801
+ defaultChecked = false,
802
+ onCheckedChange,
803
+ disabled = false,
804
+ className,
805
+ size = "default"
806
+ }) {
807
+ const [isChecked, setIsChecked] = React15.useState(defaultChecked);
808
+ const isControlled = checked !== void 0;
809
+ const currentChecked = isControlled ? checked : isChecked;
810
+ const handleClick = () => {
811
+ if (disabled) return;
812
+ const newValue = !currentChecked;
813
+ if (!isControlled) {
814
+ setIsChecked(newValue);
815
+ }
816
+ onCheckedChange?.(newValue);
817
+ };
818
+ const sizeClasses = {
819
+ sm: {
820
+ track: "h-5 w-9",
821
+ thumb: "size-4",
822
+ icon: "h-2.5 w-2.5",
823
+ translate: "data-[state=checked]:translate-x-4"
824
+ },
825
+ default: {
826
+ track: "h-6 w-11",
827
+ thumb: "size-5",
828
+ icon: "h-3 w-3",
829
+ translate: "data-[state=checked]:translate-x-5"
830
+ },
831
+ lg: {
832
+ track: "h-7 w-14",
833
+ thumb: "size-6",
834
+ icon: "h-3.5 w-3.5",
835
+ translate: "data-[state=checked]:translate-x-7"
836
+ }
837
+ };
838
+ const sizes = sizeClasses[size];
839
+ return /* @__PURE__ */ jsx(
840
+ "button",
841
+ {
842
+ type: "button",
843
+ role: "switch",
844
+ "aria-checked": currentChecked,
845
+ "aria-label": currentChecked ? "Switch to light mode" : "Switch to dark mode",
846
+ "data-slot": "theme-switch",
847
+ "data-state": currentChecked ? "checked" : "unchecked",
848
+ disabled,
849
+ onClick: handleClick,
850
+ className: cn(
851
+ "peer inline-flex shrink-0 cursor-pointer items-center rounded-full",
852
+ "border border-transparent shadow-xs transition-all outline-none",
853
+ "focus-visible:ring-[3px] focus-visible:ring-ring/50",
854
+ "disabled:cursor-not-allowed disabled:opacity-50",
855
+ "bg-input data-[state=checked]:bg-primary",
856
+ sizes.track,
857
+ className
858
+ ),
859
+ children: /* @__PURE__ */ jsx(
860
+ "span",
861
+ {
862
+ "data-state": currentChecked ? "checked" : "unchecked",
863
+ className: cn(
864
+ "pointer-events-none flex items-center justify-center rounded-full",
865
+ "bg-white shadow-lg ring-0 transition-transform",
866
+ "data-[state=unchecked]:translate-x-0.5",
867
+ sizes.thumb,
868
+ sizes.translate
869
+ ),
870
+ children: currentChecked ? /* @__PURE__ */ jsx(MoonIcon, { className: cn(sizes.icon, "text-primary") }) : /* @__PURE__ */ jsx(SunIcon, { className: cn(sizes.icon, "text-muted-foreground") })
871
+ }
872
+ )
873
+ }
874
+ );
875
+ }
876
+ function SunIcon({ className }) {
877
+ return /* @__PURE__ */ jsxs(
878
+ "svg",
879
+ {
880
+ xmlns: "http://www.w3.org/2000/svg",
881
+ viewBox: "0 0 24 24",
882
+ fill: "none",
883
+ stroke: "currentColor",
884
+ strokeWidth: "2",
885
+ strokeLinecap: "round",
886
+ strokeLinejoin: "round",
887
+ className,
888
+ children: [
889
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "4" }),
890
+ /* @__PURE__ */ jsx("path", { d: "M12 2v2" }),
891
+ /* @__PURE__ */ jsx("path", { d: "M12 20v2" }),
892
+ /* @__PURE__ */ jsx("path", { d: "m4.93 4.93 1.41 1.41" }),
893
+ /* @__PURE__ */ jsx("path", { d: "m17.66 17.66 1.41 1.41" }),
894
+ /* @__PURE__ */ jsx("path", { d: "M2 12h2" }),
895
+ /* @__PURE__ */ jsx("path", { d: "M20 12h2" }),
896
+ /* @__PURE__ */ jsx("path", { d: "m6.34 17.66-1.41 1.41" }),
897
+ /* @__PURE__ */ jsx("path", { d: "m19.07 4.93-1.41 1.41" })
898
+ ]
899
+ }
900
+ );
901
+ }
902
+ function MoonIcon({ className }) {
903
+ return /* @__PURE__ */ jsx(
904
+ "svg",
905
+ {
906
+ xmlns: "http://www.w3.org/2000/svg",
907
+ viewBox: "0 0 24 24",
908
+ fill: "none",
909
+ stroke: "currentColor",
910
+ strokeWidth: "2",
911
+ strokeLinecap: "round",
912
+ strokeLinejoin: "round",
913
+ className,
914
+ children: /* @__PURE__ */ jsx("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
915
+ }
916
+ );
917
+ }
797
918
  function ToolBarCanvas({
798
919
  className,
799
920
  ...props
@@ -803,7 +924,7 @@ function ToolBarCanvas({
803
924
  {
804
925
  "data-slot": "toolbar-canvas",
805
926
  className: cn(
806
- "inline-flex items-center gap-1 rounded-full bg-sidebar border border-sidebar-border p-1.5",
927
+ "inline-flex items-center gap-1 rounded-full bg-background border border-input p-1.5",
807
928
  className
808
929
  ),
809
930
  ...props
@@ -898,7 +1019,7 @@ function PlayerCanvasControls({
898
1019
  {
899
1020
  "data-slot": "player-canvas-controls",
900
1021
  className: cn(
901
- "flex items-center gap-2 px-1.5 py-1.5 rounded-full bg-sidebar border border-sidebar-border",
1022
+ "flex items-center gap-2 px-1.5 py-1.5 rounded-full bg-background border border-input",
902
1023
  className
903
1024
  ),
904
1025
  ...props
@@ -939,7 +1060,7 @@ function PlayerCanvasPlayButton({
939
1060
  className
940
1061
  ),
941
1062
  style: {
942
- backgroundColor: "hsl(var(--primary))",
1063
+ backgroundColor: "var(--j3m-orange-8)",
943
1064
  ...style
944
1065
  },
945
1066
  ...props,
@@ -1079,7 +1200,7 @@ function PlayerCanvasProgress({
1079
1200
  className: "absolute inset-y-0 left-0 rounded-full transition-all duration-200",
1080
1201
  style: {
1081
1202
  width: `${percentage}%`,
1082
- backgroundColor: "hsl(var(--primary))"
1203
+ backgroundColor: "var(--j3m-orange-8)"
1083
1204
  }
1084
1205
  }
1085
1206
  )
@@ -1103,7 +1224,7 @@ function Label2({
1103
1224
  );
1104
1225
  }
1105
1226
  var Form = FormProvider;
1106
- var FormFieldContext = React7.createContext(
1227
+ var FormFieldContext = React15.createContext(
1107
1228
  {}
1108
1229
  );
1109
1230
  var FormField = ({
@@ -1112,8 +1233,8 @@ var FormField = ({
1112
1233
  return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
1113
1234
  };
1114
1235
  var useFormField = () => {
1115
- const fieldContext = React7.useContext(FormFieldContext);
1116
- const itemContext = React7.useContext(FormItemContext);
1236
+ const fieldContext = React15.useContext(FormFieldContext);
1237
+ const itemContext = React15.useContext(FormItemContext);
1117
1238
  const { getFieldState } = useFormContext();
1118
1239
  const formState = useFormState({ name: fieldContext.name });
1119
1240
  const fieldState = getFieldState(fieldContext.name, formState);
@@ -1130,11 +1251,11 @@ var useFormField = () => {
1130
1251
  ...fieldState
1131
1252
  };
1132
1253
  };
1133
- var FormItemContext = React7.createContext(
1254
+ var FormItemContext = React15.createContext(
1134
1255
  {}
1135
1256
  );
1136
1257
  function FormItem({ className, ...props }) {
1137
- const id = React7.useId();
1258
+ const id = React15.useId();
1138
1259
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx(
1139
1260
  "div",
1140
1261
  {
@@ -1418,7 +1539,7 @@ var cardVariants = cva(
1418
1539
  {
1419
1540
  variants: {
1420
1541
  variant: {
1421
- default: "bg-card border shadow",
1542
+ default: "bg-card border",
1422
1543
  glass: [
1423
1544
  "glass-context",
1424
1545
  // Enables glass semantic token overrides for children
@@ -1673,186 +1794,478 @@ function AvatarFallback({
1673
1794
  }
1674
1795
  );
1675
1796
  }
1676
- function Skeleton({ className, ...props }) {
1797
+ function DropdownMenu({
1798
+ ...props
1799
+ }) {
1800
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1801
+ }
1802
+ function DropdownMenuPortal({
1803
+ ...props
1804
+ }) {
1805
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
1806
+ }
1807
+ function DropdownMenuTrigger({
1808
+ ...props
1809
+ }) {
1677
1810
  return /* @__PURE__ */ jsx(
1678
- "div",
1811
+ DropdownMenuPrimitive.Trigger,
1679
1812
  {
1680
- "data-slot": "skeleton",
1681
- className: cn("bg-accent animate-pulse rounded-md", className),
1813
+ "data-slot": "dropdown-menu-trigger",
1682
1814
  ...props
1683
1815
  }
1684
1816
  );
1685
1817
  }
1686
- function Accordion({
1818
+ function DropdownMenuContent({
1819
+ className,
1820
+ sideOffset = 4,
1687
1821
  ...props
1688
1822
  }) {
1689
- return /* @__PURE__ */ jsx(AccordionPrimitive.Root, { "data-slot": "accordion", ...props });
1823
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1824
+ DropdownMenuPrimitive.Content,
1825
+ {
1826
+ "data-slot": "dropdown-menu-content",
1827
+ sideOffset,
1828
+ className: cn(
1829
+ "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",
1830
+ className
1831
+ ),
1832
+ ...props
1833
+ }
1834
+ ) });
1690
1835
  }
1691
- function AccordionItem({
1836
+ function DropdownMenuGroup({
1837
+ ...props
1838
+ }) {
1839
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
1840
+ }
1841
+ function DropdownMenuItem({
1692
1842
  className,
1843
+ inset,
1844
+ variant = "default",
1693
1845
  ...props
1694
1846
  }) {
1695
1847
  return /* @__PURE__ */ jsx(
1696
- AccordionPrimitive.Item,
1848
+ DropdownMenuPrimitive.Item,
1697
1849
  {
1698
- "data-slot": "accordion-item",
1699
- className: cn("border-b last:border-b-0", className),
1850
+ "data-slot": "dropdown-menu-item",
1851
+ "data-inset": inset,
1852
+ "data-variant": variant,
1853
+ className: cn(
1854
+ "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",
1855
+ className
1856
+ ),
1700
1857
  ...props
1701
1858
  }
1702
1859
  );
1703
1860
  }
1704
- function AccordionTrigger({
1861
+ function DropdownMenuCheckboxItem({
1705
1862
  className,
1706
1863
  children,
1864
+ checked,
1707
1865
  ...props
1708
1866
  }) {
1709
- return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
1710
- AccordionPrimitive.Trigger,
1867
+ return /* @__PURE__ */ jsxs(
1868
+ DropdownMenuPrimitive.CheckboxItem,
1711
1869
  {
1712
- "data-slot": "accordion-trigger",
1870
+ "data-slot": "dropdown-menu-checkbox-item",
1713
1871
  className: cn(
1714
- "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
1872
+ "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",
1715
1873
  className
1716
1874
  ),
1875
+ checked,
1717
1876
  ...props,
1718
1877
  children: [
1719
- children,
1720
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
1878
+ /* @__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" }) }) }),
1879
+ children
1721
1880
  ]
1722
1881
  }
1723
- ) });
1882
+ );
1724
1883
  }
1725
- function AccordionContent({
1884
+ function DropdownMenuRadioGroup({
1885
+ ...props
1886
+ }) {
1887
+ return /* @__PURE__ */ jsx(
1888
+ DropdownMenuPrimitive.RadioGroup,
1889
+ {
1890
+ "data-slot": "dropdown-menu-radio-group",
1891
+ ...props
1892
+ }
1893
+ );
1894
+ }
1895
+ function DropdownMenuRadioItem({
1726
1896
  className,
1727
1897
  children,
1728
1898
  ...props
1729
1899
  }) {
1730
- return /* @__PURE__ */ jsx(
1731
- AccordionPrimitive.Content,
1900
+ return /* @__PURE__ */ jsxs(
1901
+ DropdownMenuPrimitive.RadioItem,
1732
1902
  {
1733
- "data-slot": "accordion-content",
1734
- className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
1903
+ "data-slot": "dropdown-menu-radio-item",
1904
+ className: cn(
1905
+ "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",
1906
+ className
1907
+ ),
1735
1908
  ...props,
1736
- children: /* @__PURE__ */ jsx("div", { className: cn("pt-0 pb-4", className), children })
1909
+ children: [
1910
+ /* @__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" }) }) }),
1911
+ children
1912
+ ]
1737
1913
  }
1738
1914
  );
1739
1915
  }
1740
- function Tabs({
1916
+ function DropdownMenuLabel({
1741
1917
  className,
1918
+ inset,
1742
1919
  ...props
1743
1920
  }) {
1744
1921
  return /* @__PURE__ */ jsx(
1745
- TabsPrimitive.Root,
1922
+ DropdownMenuPrimitive.Label,
1746
1923
  {
1747
- "data-slot": "tabs",
1748
- className: cn("flex flex-col gap-2", className),
1924
+ "data-slot": "dropdown-menu-label",
1925
+ "data-inset": inset,
1926
+ className: cn(
1927
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
1928
+ className
1929
+ ),
1749
1930
  ...props
1750
1931
  }
1751
1932
  );
1752
1933
  }
1753
- function TabsList({
1934
+ function DropdownMenuSeparator({
1754
1935
  className,
1755
1936
  ...props
1756
1937
  }) {
1757
1938
  return /* @__PURE__ */ jsx(
1758
- TabsPrimitive.List,
1939
+ DropdownMenuPrimitive.Separator,
1759
1940
  {
1760
- "data-slot": "tabs-list",
1761
- className: cn(
1762
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
1763
- className
1764
- ),
1941
+ "data-slot": "dropdown-menu-separator",
1942
+ className: cn("bg-border -mx-1 my-1 h-px", className),
1765
1943
  ...props
1766
1944
  }
1767
1945
  );
1768
1946
  }
1769
- function TabsTrigger({
1947
+ function DropdownMenuShortcut({
1770
1948
  className,
1771
1949
  ...props
1772
1950
  }) {
1773
1951
  return /* @__PURE__ */ jsx(
1774
- TabsPrimitive.Trigger,
1952
+ "span",
1775
1953
  {
1776
- "data-slot": "tabs-trigger",
1954
+ "data-slot": "dropdown-menu-shortcut",
1777
1955
  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",
1956
+ "text-muted-foreground ml-auto text-xs tracking-widest",
1779
1957
  className
1780
1958
  ),
1781
1959
  ...props
1782
1960
  }
1783
1961
  );
1784
1962
  }
1785
- function TabsContent({
1963
+ function DropdownMenuSub({
1964
+ ...props
1965
+ }) {
1966
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
1967
+ }
1968
+ function DropdownMenuSubTrigger({
1786
1969
  className,
1970
+ inset,
1971
+ children,
1787
1972
  ...props
1788
1973
  }) {
1789
- return /* @__PURE__ */ jsx(
1790
- TabsPrimitive.Content,
1974
+ return /* @__PURE__ */ jsxs(
1975
+ DropdownMenuPrimitive.SubTrigger,
1791
1976
  {
1792
- "data-slot": "tabs-content",
1793
- className: cn("flex-1 outline-none", className),
1794
- ...props
1977
+ "data-slot": "dropdown-menu-sub-trigger",
1978
+ "data-inset": inset,
1979
+ className: cn(
1980
+ "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",
1981
+ className
1982
+ ),
1983
+ ...props,
1984
+ children: [
1985
+ children,
1986
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })
1987
+ ]
1795
1988
  }
1796
1989
  );
1797
1990
  }
1798
- function Calendar({
1991
+ function DropdownMenuSubContent({
1799
1992
  className,
1800
- classNames,
1801
- showOutsideDays = true,
1802
- captionLayout = "label",
1803
- formatters,
1804
- components,
1805
1993
  ...props
1806
1994
  }) {
1807
- const defaultClassNames = getDefaultClassNames();
1808
1995
  return /* @__PURE__ */ jsx(
1809
- DayPicker,
1996
+ DropdownMenuPrimitive.SubContent,
1810
1997
  {
1811
- showOutsideDays,
1998
+ "data-slot": "dropdown-menu-sub-content",
1812
1999
  className: cn(
1813
- "bg-card group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent",
1814
- String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
1815
- String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
2000
+ "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",
1816
2001
  className
1817
2002
  ),
1818
- captionLayout,
1819
- formatters: {
1820
- formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
1821
- ...formatters
1822
- },
1823
- classNames: {
1824
- root: cn("w-fit", defaultClassNames.root),
1825
- months: cn(
1826
- "flex gap-4 flex-col md:flex-row relative",
1827
- defaultClassNames.months
1828
- ),
1829
- month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
1830
- nav: cn(
1831
- "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
1832
- defaultClassNames.nav
1833
- ),
1834
- button_previous: cn(
1835
- "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none inline-flex items-center justify-center rounded-full hover:bg-muted/50 transition-colors",
1836
- defaultClassNames.button_previous
1837
- ),
1838
- button_next: cn(
1839
- "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none inline-flex items-center justify-center rounded-full hover:bg-muted/50 transition-colors",
1840
- defaultClassNames.button_next
1841
- ),
1842
- month_caption: cn(
1843
- "flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
1844
- defaultClassNames.month_caption
1845
- ),
1846
- dropdowns: cn(
1847
- "w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
1848
- defaultClassNames.dropdowns
1849
- ),
1850
- dropdown_root: cn(
1851
- "relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
1852
- defaultClassNames.dropdown_root
2003
+ ...props
2004
+ }
2005
+ );
2006
+ }
2007
+ function UserAvatarsDropdown({
2008
+ users,
2009
+ selectedUserId,
2010
+ onSelect,
2011
+ maxVisible = 2,
2012
+ label = "All",
2013
+ className
2014
+ }) {
2015
+ const visibleUsers = users.slice(0, maxVisible);
2016
+ const overflowCount = Math.max(0, users.length - maxVisible);
2017
+ const getInitials = (name) => {
2018
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
2019
+ };
2020
+ const selectedUser = users.find((u) => u.id === selectedUserId);
2021
+ const displayLabel = selectedUserId ? selectedUser?.name || "User" : label;
2022
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
2023
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2024
+ "button",
2025
+ {
2026
+ type: "button",
2027
+ className: cn(
2028
+ "flex items-center gap-2 rounded border border-border bg-background px-3 py-1.5 text-sm transition-colors",
2029
+ "hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2030
+ className
1853
2031
  ),
1854
- dropdown: cn(
1855
- "absolute bg-popover inset-0 opacity-0",
2032
+ children: [
2033
+ /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
2034
+ visibleUsers.map((user) => /* @__PURE__ */ jsxs(
2035
+ Avatar,
2036
+ {
2037
+ className: "size-6 border-2 border-background",
2038
+ children: [
2039
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }),
2040
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[10px]", children: getInitials(user.name) })
2041
+ ]
2042
+ },
2043
+ user.id
2044
+ )),
2045
+ 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: [
2046
+ "+",
2047
+ overflowCount
2048
+ ] })
2049
+ ] }),
2050
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: displayLabel }),
2051
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 text-muted-foreground" })
2052
+ ]
2053
+ }
2054
+ ) }),
2055
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-48", children: [
2056
+ /* @__PURE__ */ jsxs(
2057
+ DropdownMenuItem,
2058
+ {
2059
+ onClick: () => onSelect(null),
2060
+ className: "flex items-center justify-between",
2061
+ children: [
2062
+ /* @__PURE__ */ jsx("span", { children: "All users" }),
2063
+ selectedUserId === null && /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" })
2064
+ ]
2065
+ }
2066
+ ),
2067
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2068
+ users.map((user) => /* @__PURE__ */ jsxs(
2069
+ DropdownMenuItem,
2070
+ {
2071
+ onClick: () => onSelect(user.id),
2072
+ className: "flex items-center justify-between",
2073
+ children: [
2074
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2075
+ /* @__PURE__ */ jsxs(Avatar, { className: "size-5", children: [
2076
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }),
2077
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[8px]", children: getInitials(user.name) })
2078
+ ] }),
2079
+ /* @__PURE__ */ jsx("span", { children: user.name })
2080
+ ] }),
2081
+ selectedUserId === user.id && /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" })
2082
+ ]
2083
+ },
2084
+ user.id
2085
+ ))
2086
+ ] })
2087
+ ] });
2088
+ }
2089
+ function Skeleton({ className, ...props }) {
2090
+ return /* @__PURE__ */ jsx(
2091
+ "div",
2092
+ {
2093
+ "data-slot": "skeleton",
2094
+ className: cn("bg-accent animate-pulse rounded-md", className),
2095
+ ...props
2096
+ }
2097
+ );
2098
+ }
2099
+ function Accordion({
2100
+ ...props
2101
+ }) {
2102
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Root, { "data-slot": "accordion", ...props });
2103
+ }
2104
+ function AccordionItem({
2105
+ className,
2106
+ ...props
2107
+ }) {
2108
+ return /* @__PURE__ */ jsx(
2109
+ AccordionPrimitive.Item,
2110
+ {
2111
+ "data-slot": "accordion-item",
2112
+ className: cn("border-b last:border-b-0", className),
2113
+ ...props
2114
+ }
2115
+ );
2116
+ }
2117
+ function AccordionTrigger({
2118
+ className,
2119
+ children,
2120
+ ...props
2121
+ }) {
2122
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
2123
+ AccordionPrimitive.Trigger,
2124
+ {
2125
+ "data-slot": "accordion-trigger",
2126
+ className: cn(
2127
+ "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
2128
+ className
2129
+ ),
2130
+ ...props,
2131
+ children: [
2132
+ children,
2133
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
2134
+ ]
2135
+ }
2136
+ ) });
2137
+ }
2138
+ function AccordionContent({
2139
+ className,
2140
+ children,
2141
+ ...props
2142
+ }) {
2143
+ return /* @__PURE__ */ jsx(
2144
+ AccordionPrimitive.Content,
2145
+ {
2146
+ "data-slot": "accordion-content",
2147
+ className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
2148
+ ...props,
2149
+ children: /* @__PURE__ */ jsx("div", { className: cn("pt-0 pb-4", className), children })
2150
+ }
2151
+ );
2152
+ }
2153
+ function Tabs({
2154
+ className,
2155
+ ...props
2156
+ }) {
2157
+ return /* @__PURE__ */ jsx(
2158
+ TabsPrimitive.Root,
2159
+ {
2160
+ "data-slot": "tabs",
2161
+ className: cn("flex flex-col gap-2", className),
2162
+ ...props
2163
+ }
2164
+ );
2165
+ }
2166
+ function TabsList({
2167
+ className,
2168
+ ...props
2169
+ }) {
2170
+ return /* @__PURE__ */ jsx(
2171
+ TabsPrimitive.List,
2172
+ {
2173
+ "data-slot": "tabs-list",
2174
+ className: cn(
2175
+ "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px] dark:bg-[#1a1a1a]",
2176
+ className
2177
+ ),
2178
+ ...props
2179
+ }
2180
+ );
2181
+ }
2182
+ function TabsTrigger({
2183
+ className,
2184
+ ...props
2185
+ }) {
2186
+ return /* @__PURE__ */ jsx(
2187
+ TabsPrimitive.Trigger,
2188
+ {
2189
+ "data-slot": "tabs-trigger",
2190
+ className: cn(
2191
+ "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",
2192
+ className
2193
+ ),
2194
+ ...props
2195
+ }
2196
+ );
2197
+ }
2198
+ function TabsContent({
2199
+ className,
2200
+ ...props
2201
+ }) {
2202
+ return /* @__PURE__ */ jsx(
2203
+ TabsPrimitive.Content,
2204
+ {
2205
+ "data-slot": "tabs-content",
2206
+ className: cn("flex-1 outline-none", className),
2207
+ ...props
2208
+ }
2209
+ );
2210
+ }
2211
+ function Calendar({
2212
+ className,
2213
+ classNames,
2214
+ showOutsideDays = true,
2215
+ captionLayout = "label",
2216
+ formatters,
2217
+ components,
2218
+ ...props
2219
+ }) {
2220
+ const defaultClassNames = getDefaultClassNames();
2221
+ return /* @__PURE__ */ jsx(
2222
+ DayPicker,
2223
+ {
2224
+ showOutsideDays,
2225
+ className: cn(
2226
+ "bg-card group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent",
2227
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
2228
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
2229
+ className
2230
+ ),
2231
+ captionLayout,
2232
+ formatters: {
2233
+ formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
2234
+ ...formatters
2235
+ },
2236
+ classNames: {
2237
+ root: cn("w-fit", defaultClassNames.root),
2238
+ months: cn(
2239
+ "flex gap-4 flex-col md:flex-row relative",
2240
+ defaultClassNames.months
2241
+ ),
2242
+ month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
2243
+ nav: cn(
2244
+ "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
2245
+ defaultClassNames.nav
2246
+ ),
2247
+ button_previous: cn(
2248
+ "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none inline-flex items-center justify-center rounded-full hover:bg-muted/50 transition-colors",
2249
+ defaultClassNames.button_previous
2250
+ ),
2251
+ button_next: cn(
2252
+ "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none inline-flex items-center justify-center rounded-full hover:bg-muted/50 transition-colors",
2253
+ defaultClassNames.button_next
2254
+ ),
2255
+ month_caption: cn(
2256
+ "flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
2257
+ defaultClassNames.month_caption
2258
+ ),
2259
+ dropdowns: cn(
2260
+ "w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
2261
+ defaultClassNames.dropdowns
2262
+ ),
2263
+ dropdown_root: cn(
2264
+ "relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
2265
+ defaultClassNames.dropdown_root
2266
+ ),
2267
+ dropdown: cn(
2268
+ "absolute bg-popover inset-0 opacity-0",
1856
2269
  defaultClassNames.dropdown
1857
2270
  ),
1858
2271
  caption_label: cn(
@@ -1944,8 +2357,8 @@ function CalendarDayButton({
1944
2357
  modifiers,
1945
2358
  ...props
1946
2359
  }) {
1947
- const ref = React7.useRef(null);
1948
- React7.useEffect(() => {
2360
+ const ref = React15.useRef(null);
2361
+ React15.useEffect(() => {
1949
2362
  if (modifiers.focused) ref.current?.focus();
1950
2363
  }, [modifiers.focused]);
1951
2364
  return /* @__PURE__ */ jsx(
@@ -1966,9 +2379,9 @@ function CalendarDayButton({
1966
2379
  }
1967
2380
  );
1968
2381
  }
1969
- var CarouselContext = React7.createContext(null);
2382
+ var CarouselContext = React15.createContext(null);
1970
2383
  function useCarousel() {
1971
- const context = React7.useContext(CarouselContext);
2384
+ const context = React15.useContext(CarouselContext);
1972
2385
  if (!context) {
1973
2386
  throw new Error("useCarousel must be used within a <Carousel />");
1974
2387
  }
@@ -1990,20 +2403,20 @@ function Carousel({
1990
2403
  },
1991
2404
  plugins
1992
2405
  );
1993
- const [canScrollPrev, setCanScrollPrev] = React7.useState(false);
1994
- const [canScrollNext, setCanScrollNext] = React7.useState(false);
1995
- const onSelect = React7.useCallback((api2) => {
2406
+ const [canScrollPrev, setCanScrollPrev] = React15.useState(false);
2407
+ const [canScrollNext, setCanScrollNext] = React15.useState(false);
2408
+ const onSelect = React15.useCallback((api2) => {
1996
2409
  if (!api2) return;
1997
2410
  setCanScrollPrev(api2.canScrollPrev());
1998
2411
  setCanScrollNext(api2.canScrollNext());
1999
2412
  }, []);
2000
- const scrollPrev = React7.useCallback(() => {
2413
+ const scrollPrev = React15.useCallback(() => {
2001
2414
  api?.scrollPrev();
2002
2415
  }, [api]);
2003
- const scrollNext = React7.useCallback(() => {
2416
+ const scrollNext = React15.useCallback(() => {
2004
2417
  api?.scrollNext();
2005
2418
  }, [api]);
2006
- const handleKeyDown = React7.useCallback(
2419
+ const handleKeyDown = React15.useCallback(
2007
2420
  (event) => {
2008
2421
  if (event.key === "ArrowLeft") {
2009
2422
  event.preventDefault();
@@ -2015,11 +2428,11 @@ function Carousel({
2015
2428
  },
2016
2429
  [scrollPrev, scrollNext]
2017
2430
  );
2018
- React7.useEffect(() => {
2431
+ React15.useEffect(() => {
2019
2432
  if (!api || !setApi) return;
2020
2433
  setApi(api);
2021
2434
  }, [api, setApi]);
2022
- React7.useEffect(() => {
2435
+ React15.useEffect(() => {
2023
2436
  if (!api) return;
2024
2437
  onSelect(api);
2025
2438
  api.on("reInit", onSelect);
@@ -2152,9 +2565,9 @@ function CarouselNext({
2152
2565
  );
2153
2566
  }
2154
2567
  var THEMES = { light: "", dark: ".dark" };
2155
- var ChartContext = React7.createContext(null);
2568
+ var ChartContext = React15.createContext(null);
2156
2569
  function useChart() {
2157
- const context = React7.useContext(ChartContext);
2570
+ const context = React15.useContext(ChartContext);
2158
2571
  if (!context) {
2159
2572
  throw new Error("useChart must be used within a <ChartContainer />");
2160
2573
  }
@@ -2167,7 +2580,7 @@ function ChartContainer({
2167
2580
  config,
2168
2581
  ...props
2169
2582
  }) {
2170
- const uniqueId = React7.useId();
2583
+ const uniqueId = React15.useId();
2171
2584
  const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
2172
2585
  return /* @__PURE__ */ jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxs(
2173
2586
  "div",
@@ -2228,7 +2641,7 @@ function ChartTooltipContent({
2228
2641
  labelKey
2229
2642
  }) {
2230
2643
  const { config } = useChart();
2231
- const tooltipLabel = React7.useMemo(() => {
2644
+ const tooltipLabel = React15.useMemo(() => {
2232
2645
  if (hideLabel || !payload?.length) {
2233
2646
  return null;
2234
2647
  }
@@ -2522,7 +2935,7 @@ var itemVariants = cva(
2522
2935
  }
2523
2936
  }
2524
2937
  );
2525
- function Item5({
2938
+ function Item6({
2526
2939
  className,
2527
2940
  variant = "default",
2528
2941
  size = "default",
@@ -2930,40 +3343,27 @@ function TooltipContent({
2930
3343
  }
2931
3344
  ) });
2932
3345
  }
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();
3346
+ function useDetectTheme() {
3347
+ const [theme, setTheme] = React15.useState("light");
3348
+ React15.useEffect(() => {
3349
+ const isDark = document.documentElement.classList.contains("dark");
3350
+ setTheme(isDark ? "dark" : "light");
3351
+ const observer = new MutationObserver((mutations) => {
3352
+ mutations.forEach((mutation) => {
3353
+ if (mutation.attributeName === "class") {
3354
+ const isDark2 = document.documentElement.classList.contains("dark");
3355
+ setTheme(isDark2 ? "dark" : "light");
3356
+ }
3357
+ });
3358
+ });
3359
+ observer.observe(document.documentElement, { attributes: true });
3360
+ return () => observer.disconnect();
3361
+ }, []);
3362
+ return theme;
3363
+ }
3364
+ var Toaster = ({ theme: themeProp, ...props }) => {
3365
+ const detectedTheme = useDetectTheme();
3366
+ const theme = themeProp ?? detectedTheme;
2967
3367
  return /* @__PURE__ */ jsx(
2968
3368
  Toaster$1,
2969
3369
  {
@@ -3466,241 +3866,78 @@ function CommandShortcut({
3466
3866
  }
3467
3867
  );
3468
3868
  }
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 });
3869
+ var SearchTrigger = React15.forwardRef(
3870
+ ({
3871
+ className,
3872
+ placeholder = "Search...",
3873
+ showShortcut = true,
3874
+ shortcutKey = "K",
3875
+ shortcutModifier = "\u2318",
3876
+ ...props
3877
+ }, ref) => {
3878
+ return /* @__PURE__ */ jsxs(
3879
+ Button,
3880
+ {
3881
+ ref,
3882
+ variant: "outline",
3883
+ "data-slot": "search-trigger",
3884
+ className: cn(
3885
+ "relative h-9 w-full justify-start rounded-full bg-background text-sm text-muted-foreground",
3886
+ "sm:w-64 sm:max-w-[280px]",
3887
+ className
3888
+ ),
3889
+ ...props,
3890
+ children: [
3891
+ /* @__PURE__ */ jsx(SearchIcon, { className: "mr-2 h-4 w-4 shrink-0" }),
3892
+ /* @__PURE__ */ jsx("span", { className: "hidden truncate sm:inline-flex", children: placeholder }),
3893
+ /* @__PURE__ */ jsx("span", { className: "truncate sm:hidden", children: "Search" }),
3894
+ 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: [
3895
+ /* @__PURE__ */ jsx("span", { className: "text-xs", children: shortcutModifier }),
3896
+ shortcutKey
3897
+ ] })
3898
+ ]
3899
+ }
3900
+ );
3901
+ }
3902
+ );
3903
+ SearchTrigger.displayName = "SearchTrigger";
3904
+ function useSearchShortcut(onOpen, key = "k") {
3905
+ React15.useEffect(() => {
3906
+ const down = (e) => {
3907
+ if (e.key.toLowerCase() === key.toLowerCase() && (e.metaKey || e.ctrlKey)) {
3908
+ e.preventDefault();
3909
+ onOpen();
3910
+ }
3911
+ };
3912
+ document.addEventListener("keydown", down);
3913
+ return () => document.removeEventListener("keydown", down);
3914
+ }, [onOpen, key]);
3478
3915
  }
3479
- function DropdownMenuTrigger({
3916
+ function Menubar({
3917
+ className,
3480
3918
  ...props
3481
3919
  }) {
3482
3920
  return /* @__PURE__ */ jsx(
3483
- DropdownMenuPrimitive.Trigger,
3921
+ MenubarPrimitive.Root,
3484
3922
  {
3485
- "data-slot": "dropdown-menu-trigger",
3923
+ "data-slot": "menubar",
3924
+ className: cn(
3925
+ "bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs",
3926
+ className
3927
+ ),
3486
3928
  ...props
3487
3929
  }
3488
3930
  );
3489
3931
  }
3490
- function DropdownMenuContent({
3491
- className,
3492
- sideOffset = 4,
3932
+ function MenubarMenu({
3493
3933
  ...props
3494
3934
  }) {
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
- ) });
3935
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Menu, { "data-slot": "menubar-menu", ...props });
3507
3936
  }
3508
- function DropdownMenuGroup({
3937
+ function MenubarGroup({
3509
3938
  ...props
3510
3939
  }) {
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
- );
3678
- }
3679
- function Menubar({
3680
- className,
3681
- ...props
3682
- }) {
3683
- return /* @__PURE__ */ jsx(
3684
- MenubarPrimitive.Root,
3685
- {
3686
- "data-slot": "menubar",
3687
- className: cn(
3688
- "bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs",
3689
- className
3690
- ),
3691
- ...props
3692
- }
3693
- );
3694
- }
3695
- function MenubarMenu({
3696
- ...props
3697
- }) {
3698
- return /* @__PURE__ */ jsx(MenubarPrimitive.Menu, { "data-slot": "menubar-menu", ...props });
3699
- }
3700
- function MenubarGroup({
3701
- ...props
3702
- }) {
3703
- return /* @__PURE__ */ jsx(MenubarPrimitive.Group, { "data-slot": "menubar-group", ...props });
3940
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Group, { "data-slot": "menubar-group", ...props });
3704
3941
  }
3705
3942
  function MenubarPortal({
3706
3943
  ...props
@@ -4693,9 +4930,9 @@ var SIDEBAR_WIDTH = "16rem";
4693
4930
  var SIDEBAR_WIDTH_MOBILE = "18rem";
4694
4931
  var SIDEBAR_WIDTH_ICON = "3rem";
4695
4932
  var SIDEBAR_KEYBOARD_SHORTCUT = "b";
4696
- var SidebarContext = React7.createContext(null);
4933
+ var SidebarContext = React15.createContext(null);
4697
4934
  function useSidebar() {
4698
- const context = React7.useContext(SidebarContext);
4935
+ const context = React15.useContext(SidebarContext);
4699
4936
  if (!context) {
4700
4937
  throw new Error("useSidebar must be used within a SidebarProvider.");
4701
4938
  }
@@ -4711,10 +4948,10 @@ function SidebarProvider({
4711
4948
  ...props
4712
4949
  }) {
4713
4950
  const isMobile = useIsMobile();
4714
- const [openMobile, setOpenMobile] = React7.useState(false);
4715
- const [_open, _setOpen] = React7.useState(defaultOpen);
4951
+ const [openMobile, setOpenMobile] = React15.useState(false);
4952
+ const [_open, _setOpen] = React15.useState(defaultOpen);
4716
4953
  const open = openProp ?? _open;
4717
- const setOpen = React7.useCallback(
4954
+ const setOpen = React15.useCallback(
4718
4955
  (value) => {
4719
4956
  const openState = typeof value === "function" ? value(open) : value;
4720
4957
  if (setOpenProp) {
@@ -4726,10 +4963,10 @@ function SidebarProvider({
4726
4963
  },
4727
4964
  [setOpenProp, open]
4728
4965
  );
4729
- const toggleSidebar = React7.useCallback(() => {
4966
+ const toggleSidebar = React15.useCallback(() => {
4730
4967
  return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
4731
4968
  }, [isMobile, setOpen, setOpenMobile]);
4732
- React7.useEffect(() => {
4969
+ React15.useEffect(() => {
4733
4970
  const handleKeyDown = (event) => {
4734
4971
  if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
4735
4972
  event.preventDefault();
@@ -4740,7 +4977,7 @@ function SidebarProvider({
4740
4977
  return () => window.removeEventListener("keydown", handleKeyDown);
4741
4978
  }, [toggleSidebar]);
4742
4979
  const state = open ? "expanded" : "collapsed";
4743
- const contextValue = React7.useMemo(
4980
+ const contextValue = React15.useMemo(
4744
4981
  () => ({
4745
4982
  state,
4746
4983
  open,
@@ -5198,7 +5435,7 @@ function SidebarMenuSkeleton({
5198
5435
  showIcon = false,
5199
5436
  ...props
5200
5437
  }) {
5201
- const width = React7.useMemo(() => {
5438
+ const width = React15.useMemo(() => {
5202
5439
  return `${Math.floor(Math.random() * 40) + 50}%`;
5203
5440
  }, []);
5204
5441
  return /* @__PURE__ */ jsxs(
@@ -5296,8 +5533,7 @@ var sectionVariants = cva(
5296
5533
  default: [
5297
5534
  "bg-[var(--color-bg-surface)]",
5298
5535
  "border border-[var(--color-border-subtle)]",
5299
- "text-[var(--color-text-main)]",
5300
- "shadow-sm"
5536
+ "text-[var(--color-text-main)]"
5301
5537
  ].join(" "),
5302
5538
  // Glass Light - frosted glass for dark or image backgrounds
5303
5539
  "glass-light": [
@@ -5342,7 +5578,7 @@ var sectionVariants = cva(
5342
5578
  }
5343
5579
  );
5344
5580
  var isGlassVariant = (variant) => variant?.startsWith("glass-") ?? false;
5345
- var Section = React7.forwardRef(
5581
+ var Section = React15.forwardRef(
5346
5582
  ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
5347
5583
  "section",
5348
5584
  {
@@ -5354,7 +5590,7 @@ var Section = React7.forwardRef(
5354
5590
  )
5355
5591
  );
5356
5592
  Section.displayName = "Section";
5357
- var SectionHeader = React7.forwardRef(
5593
+ var SectionHeader = React15.forwardRef(
5358
5594
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5359
5595
  "div",
5360
5596
  {
@@ -5369,7 +5605,7 @@ var SectionHeader = React7.forwardRef(
5369
5605
  )
5370
5606
  );
5371
5607
  SectionHeader.displayName = "SectionHeader";
5372
- var SectionTitle = React7.forwardRef(
5608
+ var SectionTitle = React15.forwardRef(
5373
5609
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5374
5610
  "h2",
5375
5611
  {
@@ -5383,7 +5619,7 @@ var SectionTitle = React7.forwardRef(
5383
5619
  )
5384
5620
  );
5385
5621
  SectionTitle.displayName = "SectionTitle";
5386
- var SectionDescription = React7.forwardRef(
5622
+ var SectionDescription = React15.forwardRef(
5387
5623
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5388
5624
  "p",
5389
5625
  {
@@ -5397,7 +5633,7 @@ var SectionDescription = React7.forwardRef(
5397
5633
  )
5398
5634
  );
5399
5635
  SectionDescription.displayName = "SectionDescription";
5400
- var SectionContent = React7.forwardRef(
5636
+ var SectionContent = React15.forwardRef(
5401
5637
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5402
5638
  "div",
5403
5639
  {
@@ -5411,7 +5647,7 @@ var SectionContent = React7.forwardRef(
5411
5647
  )
5412
5648
  );
5413
5649
  SectionContent.displayName = "SectionContent";
5414
- var SectionFooter = React7.forwardRef(
5650
+ var SectionFooter = React15.forwardRef(
5415
5651
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5416
5652
  "div",
5417
5653
  {
@@ -5427,7 +5663,3182 @@ var SectionFooter = React7.forwardRef(
5427
5663
  )
5428
5664
  );
5429
5665
  SectionFooter.displayName = "SectionFooter";
5666
+ function SearchForm({ ...props }) {
5667
+ return /* @__PURE__ */ jsx("form", { ...props, children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
5668
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "search", className: "sr-only", children: "Search" }),
5669
+ /* @__PURE__ */ jsx(
5670
+ SidebarInput,
5671
+ {
5672
+ id: "search",
5673
+ placeholder: "Type to search...",
5674
+ className: "h-8 pl-7"
5675
+ }
5676
+ ),
5677
+ /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 opacity-50 select-none" })
5678
+ ] }) });
5679
+ }
5680
+ function SiteHeader({
5681
+ trigger,
5682
+ breadcrumbs = [
5683
+ { label: "Building Your Application", href: "#" },
5684
+ { label: "Data Fetching" }
5685
+ ],
5686
+ showSearch = true,
5687
+ className,
5688
+ children
5689
+ }) {
5690
+ return /* @__PURE__ */ jsx(
5691
+ "header",
5692
+ {
5693
+ "data-slot": "site-header",
5694
+ className: cn(
5695
+ "bg-sidebar text-sidebar-foreground sticky top-0 z-50 flex w-full items-center border-b border-sidebar-border",
5696
+ className
5697
+ ),
5698
+ 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: [
5699
+ trigger,
5700
+ trigger && /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
5701
+ /* @__PURE__ */ jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxs(React15.Fragment, { children: [
5702
+ index > 0 && /* @__PURE__ */ jsx(BreadcrumbSeparator, {}),
5703
+ /* @__PURE__ */ jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) })
5704
+ ] }, index)) }) }),
5705
+ showSearch && /* @__PURE__ */ jsx(SearchForm, { className: "w-full sm:ml-auto sm:w-auto" }),
5706
+ children
5707
+ ] })
5708
+ }
5709
+ );
5710
+ }
5711
+ function NavMain({ items, label = "Platform" }) {
5712
+ return /* @__PURE__ */ jsxs(SidebarGroup, { children: [
5713
+ /* @__PURE__ */ jsx(SidebarGroupLabel, { children: label }),
5714
+ /* @__PURE__ */ jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsx(Collapsible, { asChild: true, defaultOpen: item.isActive, children: /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
5715
+ /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, tooltip: item.title, children: /* @__PURE__ */ jsxs("a", { href: item.url, children: [
5716
+ item.icon && /* @__PURE__ */ jsx(item.icon, {}),
5717
+ /* @__PURE__ */ jsx("span", { children: item.title })
5718
+ ] }) }),
5719
+ item.items?.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
5720
+ /* @__PURE__ */ jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs(SidebarMenuAction, { className: "data-[state=open]:rotate-90", children: [
5721
+ /* @__PURE__ */ jsx(ChevronRightIcon, {}),
5722
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Toggle" })
5723
+ ] }) }),
5724
+ /* @__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)) }) })
5725
+ ] }) : null
5726
+ ] }) }, item.title)) })
5727
+ ] });
5728
+ }
5729
+ function NavProjects({ projects, label = "Projects" }) {
5730
+ return /* @__PURE__ */ jsxs(SidebarGroup, { className: "group-data-[collapsible=icon]:hidden", children: [
5731
+ /* @__PURE__ */ jsx(SidebarGroupLabel, { children: label }),
5732
+ /* @__PURE__ */ jsxs(SidebarMenu, { children: [
5733
+ projects.map((item) => /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
5734
+ /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, children: /* @__PURE__ */ jsxs("a", { href: item.url, children: [
5735
+ /* @__PURE__ */ jsx(item.icon, {}),
5736
+ /* @__PURE__ */ jsx("span", { children: item.name })
5737
+ ] }) }),
5738
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
5739
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(SidebarMenuAction, { showOnHover: true, children: [
5740
+ /* @__PURE__ */ jsx(MoreHorizontalIcon, {}),
5741
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "More" })
5742
+ ] }) }),
5743
+ /* @__PURE__ */ jsxs(
5744
+ DropdownMenuContent,
5745
+ {
5746
+ className: "w-48 rounded-[var(--j3m-radius-m)]",
5747
+ side: "right",
5748
+ align: "start",
5749
+ sideOffset: 8,
5750
+ children: [
5751
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5752
+ /* @__PURE__ */ jsx(FolderIcon, { className: "text-muted-foreground" }),
5753
+ /* @__PURE__ */ jsx("span", { children: "View Project" })
5754
+ ] }),
5755
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5756
+ /* @__PURE__ */ jsx(ShareIcon, { className: "text-muted-foreground" }),
5757
+ /* @__PURE__ */ jsx("span", { children: "Share Project" })
5758
+ ] }),
5759
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5760
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5761
+ /* @__PURE__ */ jsx(TrashIcon, { className: "text-muted-foreground" }),
5762
+ /* @__PURE__ */ jsx("span", { children: "Delete Project" })
5763
+ ] })
5764
+ ]
5765
+ }
5766
+ )
5767
+ ] })
5768
+ ] }, item.name)),
5769
+ /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, { className: "text-sidebar-foreground/70", children: [
5770
+ /* @__PURE__ */ jsx(MoreHorizontalIcon, { className: "text-sidebar-foreground/70" }),
5771
+ /* @__PURE__ */ jsx("span", { children: "More" })
5772
+ ] }) })
5773
+ ] })
5774
+ ] });
5775
+ }
5776
+ function NavSecondary({ items, ...props }) {
5777
+ 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: [
5778
+ /* @__PURE__ */ jsx(item.icon, {}),
5779
+ /* @__PURE__ */ jsx("span", { children: item.title })
5780
+ ] }) }) }, item.title)) }) }) });
5781
+ }
5782
+ function NavUser({ user }) {
5783
+ return /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
5784
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
5785
+ SidebarMenuButton,
5786
+ {
5787
+ size: "lg",
5788
+ className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
5789
+ children: [
5790
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
5791
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
5792
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
5793
+ ] }),
5794
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
5795
+ /* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: user.name }),
5796
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: user.email })
5797
+ ] }),
5798
+ /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "ml-auto size-4" })
5799
+ ]
5800
+ }
5801
+ ) }),
5802
+ /* @__PURE__ */ jsxs(
5803
+ DropdownMenuContent,
5804
+ {
5805
+ className: "w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-[var(--j3m-radius-m)]",
5806
+ side: "right",
5807
+ align: "end",
5808
+ sideOffset: 8,
5809
+ children: [
5810
+ /* @__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: [
5811
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
5812
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
5813
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
5814
+ ] }),
5815
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
5816
+ /* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: user.name }),
5817
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: user.email })
5818
+ ] })
5819
+ ] }) }),
5820
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5821
+ /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5822
+ /* @__PURE__ */ jsx(SparklesIcon, {}),
5823
+ "Upgrade to Pro"
5824
+ ] }) }),
5825
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5826
+ /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
5827
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5828
+ /* @__PURE__ */ jsx(BadgeCheckIcon, {}),
5829
+ "Account"
5830
+ ] }),
5831
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5832
+ /* @__PURE__ */ jsx(CreditCardIcon, {}),
5833
+ "Billing"
5834
+ ] }),
5835
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5836
+ /* @__PURE__ */ jsx(BellIcon, {}),
5837
+ "Notifications"
5838
+ ] })
5839
+ ] }),
5840
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
5841
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
5842
+ /* @__PURE__ */ jsx(LogOutIcon, {}),
5843
+ "Log out"
5844
+ ] })
5845
+ ]
5846
+ }
5847
+ )
5848
+ ] }) }) });
5849
+ }
5850
+
5851
+ // src/components/event-calendar/types.ts
5852
+ var DEFAULT_WORKING_HOURS = {
5853
+ 0: { from: 0, to: 0 },
5854
+ // Sunday - closed
5855
+ 1: { from: 9, to: 17 },
5856
+ // Monday
5857
+ 2: { from: 9, to: 17 },
5858
+ // Tuesday
5859
+ 3: { from: 9, to: 17 },
5860
+ // Wednesday
5861
+ 4: { from: 9, to: 17 },
5862
+ // Thursday
5863
+ 5: { from: 9, to: 17 },
5864
+ // Friday
5865
+ 6: { from: 0, to: 0 }
5866
+ // Saturday - closed
5867
+ };
5868
+ var DEFAULT_VISIBLE_HOURS = { from: 0, to: 24 };
5869
+ var EVENT_COLORS = {
5870
+ blue: {
5871
+ bg: "bg-blue-500/20",
5872
+ text: "text-blue-700 dark:text-blue-300",
5873
+ border: "border-blue-500"
5874
+ },
5875
+ green: {
5876
+ bg: "bg-green-500/20",
5877
+ text: "text-green-700 dark:text-green-300",
5878
+ border: "border-green-500"
5879
+ },
5880
+ red: {
5881
+ bg: "bg-red-500/20",
5882
+ text: "text-red-700 dark:text-red-300",
5883
+ border: "border-red-500"
5884
+ },
5885
+ yellow: {
5886
+ bg: "bg-yellow-500/20",
5887
+ text: "text-yellow-700 dark:text-yellow-300",
5888
+ border: "border-yellow-500"
5889
+ },
5890
+ purple: {
5891
+ bg: "bg-purple-500/20",
5892
+ text: "text-purple-700 dark:text-purple-300",
5893
+ border: "border-purple-500"
5894
+ },
5895
+ orange: {
5896
+ bg: "bg-primary/20",
5897
+ text: "text-primary dark:text-orange-300",
5898
+ border: "border-primary"
5899
+ }
5900
+ };
5901
+ var VIEW_LABELS = {
5902
+ month: "Month",
5903
+ week: "Week",
5904
+ day: "Day",
5905
+ year: "Year",
5906
+ agenda: "Agenda"
5907
+ };
5908
+ var BADGE_VARIANT_LABELS = {
5909
+ dot: "Dot",
5910
+ colored: "Colored",
5911
+ mixed: "Mixed"
5912
+ };
5913
+ var CalendarContext = React15.createContext(null);
5914
+ function EventCalendarProvider({
5915
+ children,
5916
+ events: initialEvents = [],
5917
+ users: initialUsers = [],
5918
+ defaultDate = /* @__PURE__ */ new Date(),
5919
+ defaultView = "month",
5920
+ defaultBadgeVariant = "colored",
5921
+ defaultUserId = null,
5922
+ defaultWorkingHours = DEFAULT_WORKING_HOURS,
5923
+ defaultVisibleHours = DEFAULT_VISIBLE_HOURS,
5924
+ onEventAdd,
5925
+ onEventUpdate,
5926
+ onEventDelete
5927
+ }) {
5928
+ const [selectedDate, setSelectedDate] = React15.useState(defaultDate);
5929
+ const [selectedUserId, setSelectedUserId] = React15.useState(defaultUserId);
5930
+ const [events, setEventsState] = React15.useState(initialEvents);
5931
+ const [users] = React15.useState(initialUsers);
5932
+ const [badgeVariant, setBadgeVariant] = React15.useState(defaultBadgeVariant);
5933
+ const [view, setView] = React15.useState(defaultView);
5934
+ const [workingHours, setWorkingHours] = React15.useState(defaultWorkingHours);
5935
+ const [visibleHours, setVisibleHours] = React15.useState(defaultVisibleHours);
5936
+ React15.useEffect(() => {
5937
+ setEventsState(initialEvents);
5938
+ }, [initialEvents]);
5939
+ const setEvents = React15.useCallback((newEvents) => {
5940
+ setEventsState(newEvents);
5941
+ }, []);
5942
+ const addEvent = React15.useCallback((event) => {
5943
+ setEventsState((prev) => [...prev, event]);
5944
+ onEventAdd?.(event);
5945
+ }, [onEventAdd]);
5946
+ const updateEvent = React15.useCallback((event) => {
5947
+ setEventsState(
5948
+ (prev) => prev.map((e) => e.id === event.id ? event : e)
5949
+ );
5950
+ onEventUpdate?.(event);
5951
+ }, [onEventUpdate]);
5952
+ const deleteEvent = React15.useCallback((eventId) => {
5953
+ setEventsState((prev) => prev.filter((e) => e.id !== eventId));
5954
+ onEventDelete?.(eventId);
5955
+ }, [onEventDelete]);
5956
+ const goToToday = React15.useCallback(() => {
5957
+ setSelectedDate(/* @__PURE__ */ new Date());
5958
+ }, []);
5959
+ const goToPrevious = React15.useCallback(() => {
5960
+ setSelectedDate((current) => {
5961
+ switch (view) {
5962
+ case "day":
5963
+ return subDays(current, 1);
5964
+ case "week":
5965
+ return subWeeks(current, 1);
5966
+ case "month":
5967
+ return subMonths(current, 1);
5968
+ case "year":
5969
+ return subYears(current, 1);
5970
+ case "agenda":
5971
+ return subMonths(current, 1);
5972
+ default:
5973
+ return current;
5974
+ }
5975
+ });
5976
+ }, [view]);
5977
+ const goToNext = React15.useCallback(() => {
5978
+ setSelectedDate((current) => {
5979
+ switch (view) {
5980
+ case "day":
5981
+ return addDays(current, 1);
5982
+ case "week":
5983
+ return addWeeks(current, 1);
5984
+ case "month":
5985
+ return addMonths(current, 1);
5986
+ case "year":
5987
+ return addYears(current, 1);
5988
+ case "agenda":
5989
+ return addMonths(current, 1);
5990
+ default:
5991
+ return current;
5992
+ }
5993
+ });
5994
+ }, [view]);
5995
+ const contextValue = React15.useMemo(
5996
+ () => ({
5997
+ // State
5998
+ selectedDate,
5999
+ selectedUserId,
6000
+ events,
6001
+ users,
6002
+ badgeVariant,
6003
+ view,
6004
+ workingHours,
6005
+ visibleHours,
6006
+ // Actions
6007
+ setSelectedDate,
6008
+ setSelectedUserId,
6009
+ setEvents,
6010
+ addEvent,
6011
+ updateEvent,
6012
+ deleteEvent,
6013
+ setBadgeVariant,
6014
+ setView,
6015
+ setWorkingHours,
6016
+ setVisibleHours,
6017
+ goToToday,
6018
+ goToPrevious,
6019
+ goToNext
6020
+ }),
6021
+ [
6022
+ selectedDate,
6023
+ selectedUserId,
6024
+ events,
6025
+ users,
6026
+ badgeVariant,
6027
+ view,
6028
+ workingHours,
6029
+ visibleHours,
6030
+ setEvents,
6031
+ addEvent,
6032
+ updateEvent,
6033
+ deleteEvent,
6034
+ goToToday,
6035
+ goToPrevious,
6036
+ goToNext
6037
+ ]
6038
+ );
6039
+ return /* @__PURE__ */ jsx(CalendarContext.Provider, { value: contextValue, children });
6040
+ }
6041
+ function useEventCalendar() {
6042
+ const context = React15.useContext(CalendarContext);
6043
+ if (!context) {
6044
+ throw new Error("useEventCalendar must be used within an EventCalendarProvider");
6045
+ }
6046
+ return context;
6047
+ }
6048
+ function useFilteredEvents() {
6049
+ const { events, selectedUserId } = useEventCalendar();
6050
+ return React15.useMemo(() => {
6051
+ if (!selectedUserId) return events;
6052
+ return events.filter((event) => event.user.id === selectedUserId);
6053
+ }, [events, selectedUserId]);
6054
+ }
6055
+ function useEventsInRange(startDate, endDate) {
6056
+ const filteredEvents = useFilteredEvents();
6057
+ return React15.useMemo(() => {
6058
+ return filteredEvents.filter((event) => {
6059
+ const eventStart = new Date(event.startDate);
6060
+ const eventEnd = new Date(event.endDate);
6061
+ return eventStart <= endDate && eventEnd >= startDate;
6062
+ });
6063
+ }, [filteredEvents, startDate, endDate]);
6064
+ }
6065
+ function rangeText(view, date) {
6066
+ const formatString = "MMM d, yyyy";
6067
+ let start;
6068
+ let end;
6069
+ switch (view) {
6070
+ case "agenda":
6071
+ start = startOfMonth(date);
6072
+ end = endOfMonth(date);
6073
+ break;
6074
+ case "year":
6075
+ start = startOfYear(date);
6076
+ end = endOfYear(date);
6077
+ break;
6078
+ case "month":
6079
+ start = startOfMonth(date);
6080
+ end = endOfMonth(date);
6081
+ break;
6082
+ case "week":
6083
+ start = startOfWeek(date);
6084
+ end = endOfWeek(date);
6085
+ break;
6086
+ case "day":
6087
+ return format(date, formatString);
6088
+ default:
6089
+ return "Error while formatting";
6090
+ }
6091
+ return `${format(start, formatString)} - ${format(end, formatString)}`;
6092
+ }
6093
+ function navigateDate(date, view, direction) {
6094
+ const operations = {
6095
+ agenda: direction === "next" ? addMonths : subMonths,
6096
+ year: direction === "next" ? addYears : subYears,
6097
+ month: direction === "next" ? addMonths : subMonths,
6098
+ week: direction === "next" ? addWeeks : subWeeks,
6099
+ day: direction === "next" ? addDays : subDays
6100
+ };
6101
+ return operations[view](date, 1);
6102
+ }
6103
+ function getEventsCount(events, date, view) {
6104
+ const compareFns = {
6105
+ agenda: isSameMonth,
6106
+ year: isSameYear,
6107
+ day: isSameDay,
6108
+ week: isSameWeek,
6109
+ month: isSameMonth
6110
+ };
6111
+ return events.filter(
6112
+ (event) => compareFns[view](new Date(event.startDate), date)
6113
+ ).length;
6114
+ }
6115
+ function getCurrentEvents(events) {
6116
+ const now = /* @__PURE__ */ new Date();
6117
+ return events.filter(
6118
+ (event) => isWithinInterval(now, {
6119
+ start: parseISO(event.startDate),
6120
+ end: parseISO(event.endDate)
6121
+ })
6122
+ ) || [];
6123
+ }
6124
+ function groupEvents(dayEvents) {
6125
+ const sortedEvents = dayEvents.sort(
6126
+ (a, b) => parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime()
6127
+ );
6128
+ const groups = [];
6129
+ for (const event of sortedEvents) {
6130
+ const eventStart = parseISO(event.startDate);
6131
+ let placed = false;
6132
+ for (const group of groups) {
6133
+ const lastEventInGroup = group[group.length - 1];
6134
+ const lastEventEnd = parseISO(lastEventInGroup.endDate);
6135
+ if (eventStart >= lastEventEnd) {
6136
+ group.push(event);
6137
+ placed = true;
6138
+ break;
6139
+ }
6140
+ }
6141
+ if (!placed) groups.push([event]);
6142
+ }
6143
+ return groups;
6144
+ }
6145
+ function getEventBlockStyle(event, day, groupIndex, groupSize, visibleHoursRange, hourHeight = 96) {
6146
+ const startDate = parseISO(event.startDate);
6147
+ const endDate = parseISO(event.endDate);
6148
+ const dayStart = new Date(day);
6149
+ dayStart.setHours(0, 0, 0, 0);
6150
+ const eventStart = startDate < dayStart ? dayStart : startDate;
6151
+ const startMinutes = differenceInMinutes(eventStart, dayStart);
6152
+ const durationMinutes = differenceInMinutes(endDate, eventStart);
6153
+ const visibleStartMinutes = (visibleHoursRange?.from ?? 0) * 60;
6154
+ const topMinutes = startMinutes - visibleStartMinutes;
6155
+ const topPx = topMinutes / 60 * hourHeight;
6156
+ const heightPx = Math.max(durationMinutes / 60 * hourHeight, hourHeight / 4);
6157
+ const width = 100 / groupSize;
6158
+ const left = groupIndex * width;
6159
+ return {
6160
+ top: `${topPx}px`,
6161
+ height: `${heightPx}px`,
6162
+ width: `${width}%`,
6163
+ left: `${left}%`
6164
+ };
6165
+ }
6166
+ function isWorkingHour(day, hour, workingHours) {
6167
+ const dayIndex = day.getDay();
6168
+ const dayHours = workingHours[dayIndex];
6169
+ return hour >= dayHours.from && hour < dayHours.to;
6170
+ }
6171
+ function getVisibleHours(visibleHours, singleDayEvents) {
6172
+ let earliestEventHour = visibleHours.from;
6173
+ let latestEventHour = visibleHours.to;
6174
+ singleDayEvents.forEach((event) => {
6175
+ const startHour = parseISO(event.startDate).getHours();
6176
+ const endTime = parseISO(event.endDate);
6177
+ const endHour = endTime.getHours() + (endTime.getMinutes() > 0 ? 1 : 0);
6178
+ if (startHour < earliestEventHour) earliestEventHour = startHour;
6179
+ if (endHour > latestEventHour) latestEventHour = endHour;
6180
+ });
6181
+ latestEventHour = Math.min(latestEventHour, 24);
6182
+ const hours = Array.from(
6183
+ { length: latestEventHour - earliestEventHour },
6184
+ (_, i) => i + earliestEventHour
6185
+ );
6186
+ return { hours, earliestEventHour, latestEventHour };
6187
+ }
6188
+ function getCalendarCells(selectedDate) {
6189
+ const currentYear = selectedDate.getFullYear();
6190
+ const currentMonth = selectedDate.getMonth();
6191
+ const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
6192
+ const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay();
6193
+ const daysInMonth = getDaysInMonth(currentYear, currentMonth);
6194
+ const firstDayOfMonth = getFirstDayOfMonth(currentYear, currentMonth);
6195
+ const daysInPrevMonth = getDaysInMonth(currentYear, currentMonth - 1);
6196
+ const totalDays = firstDayOfMonth + daysInMonth;
6197
+ const prevMonthCells = Array.from({ length: firstDayOfMonth }, (_, i) => ({
6198
+ day: daysInPrevMonth - firstDayOfMonth + i + 1,
6199
+ currentMonth: false,
6200
+ date: new Date(
6201
+ currentYear,
6202
+ currentMonth - 1,
6203
+ daysInPrevMonth - firstDayOfMonth + i + 1
6204
+ )
6205
+ }));
6206
+ const currentMonthCells = Array.from({ length: daysInMonth }, (_, i) => ({
6207
+ day: i + 1,
6208
+ currentMonth: true,
6209
+ date: new Date(currentYear, currentMonth, i + 1)
6210
+ }));
6211
+ const nextMonthCells = Array.from(
6212
+ { length: (7 - totalDays % 7) % 7 },
6213
+ (_, i) => ({
6214
+ day: i + 1,
6215
+ currentMonth: false,
6216
+ date: new Date(currentYear, currentMonth + 1, i + 1)
6217
+ })
6218
+ );
6219
+ return [...prevMonthCells, ...currentMonthCells, ...nextMonthCells];
6220
+ }
6221
+ function calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate) {
6222
+ const monthStart = startOfMonth(selectedDate);
6223
+ const monthEnd = endOfMonth(selectedDate);
6224
+ const eventPositions = {};
6225
+ const occupiedPositions = {};
6226
+ eachDayOfInterval({ start: monthStart, end: monthEnd }).forEach((day) => {
6227
+ occupiedPositions[day.toISOString()] = [false, false, false];
6228
+ });
6229
+ const sortedEvents = [
6230
+ ...multiDayEvents.sort((a, b) => {
6231
+ const aDuration = differenceInDays(
6232
+ parseISO(a.endDate),
6233
+ parseISO(a.startDate)
6234
+ );
6235
+ const bDuration = differenceInDays(
6236
+ parseISO(b.endDate),
6237
+ parseISO(b.startDate)
6238
+ );
6239
+ return bDuration - aDuration || parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime();
6240
+ }),
6241
+ ...singleDayEvents.sort(
6242
+ (a, b) => parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime()
6243
+ )
6244
+ ];
6245
+ sortedEvents.forEach((event) => {
6246
+ const eventStart = parseISO(event.startDate);
6247
+ const eventEnd = parseISO(event.endDate);
6248
+ const eventDays = eachDayOfInterval({
6249
+ start: eventStart < monthStart ? monthStart : eventStart,
6250
+ end: eventEnd > monthEnd ? monthEnd : eventEnd
6251
+ });
6252
+ let position = -1;
6253
+ for (let i = 0; i < 3; i++) {
6254
+ if (eventDays.every((day) => {
6255
+ const dayPositions = occupiedPositions[startOfDay(day).toISOString()];
6256
+ return dayPositions && !dayPositions[i];
6257
+ })) {
6258
+ position = i;
6259
+ break;
6260
+ }
6261
+ }
6262
+ if (position !== -1) {
6263
+ eventDays.forEach((day) => {
6264
+ const dayKey = startOfDay(day).toISOString();
6265
+ occupiedPositions[dayKey][position] = true;
6266
+ });
6267
+ eventPositions[event.id] = position;
6268
+ }
6269
+ });
6270
+ return eventPositions;
6271
+ }
6272
+ function getMonthCellEvents(date, events, eventPositions) {
6273
+ const eventsForDate = events.filter((event) => {
6274
+ const eventStart = parseISO(event.startDate);
6275
+ const eventEnd = parseISO(event.endDate);
6276
+ return date >= eventStart && date <= eventEnd || isSameDay(date, eventStart) || isSameDay(date, eventEnd);
6277
+ });
6278
+ return eventsForDate.map((event) => ({
6279
+ ...event,
6280
+ position: eventPositions[event.id] ?? -1,
6281
+ isMultiDay: event.startDate !== event.endDate
6282
+ })).sort((a, b) => {
6283
+ if (a.isMultiDay && !b.isMultiDay) return -1;
6284
+ if (!a.isMultiDay && b.isMultiDay) return 1;
6285
+ return a.position - b.position;
6286
+ });
6287
+ }
6288
+ function getMonthDays(date, weekStartsOn = 0) {
6289
+ const start = startOfWeek(startOfMonth(date), { weekStartsOn });
6290
+ const end = endOfWeek(endOfMonth(date), { weekStartsOn });
6291
+ return eachDayOfInterval({ start, end });
6292
+ }
6293
+ function getWeekDays(date, weekStartsOn = 0) {
6294
+ const start = startOfWeek(date, { weekStartsOn });
6295
+ const end = endOfWeek(date, { weekStartsOn });
6296
+ return eachDayOfInterval({ start, end });
6297
+ }
6298
+ function getDayHours(date, start = 0, end = 24) {
6299
+ const dayStart = setMinutes(setHours(date, start), 0);
6300
+ const dayEnd = setMinutes(setHours(date, end - 1), 59);
6301
+ return eachHourOfInterval({ start: dayStart, end: dayEnd });
6302
+ }
6303
+ function getYearMonths(date) {
6304
+ const start = startOfYear(date);
6305
+ const months = [];
6306
+ for (let i = 0; i < 12; i++) {
6307
+ months.push(new Date(start.getFullYear(), i, 1));
6308
+ }
6309
+ return months;
6310
+ }
6311
+ function getEventsForDate(events, date) {
6312
+ return events.filter((event) => {
6313
+ const eventStart = parseISO(event.startDate);
6314
+ const eventEnd = parseISO(event.endDate);
6315
+ return isWithinInterval(date, {
6316
+ start: startOfDay(eventStart),
6317
+ end: endOfDay(eventEnd)
6318
+ }) || isSameDay(eventStart, date) || isSameDay(eventEnd, date);
6319
+ });
6320
+ }
6321
+ function getEventsInRange(events, start, end) {
6322
+ return events.filter((event) => {
6323
+ const eventStart = parseISO(event.startDate);
6324
+ const eventEnd = parseISO(event.endDate);
6325
+ return eventStart >= start && eventStart <= end || eventEnd >= start && eventEnd <= end || eventStart <= start && eventEnd >= end;
6326
+ });
6327
+ }
6328
+ function splitEventsByDuration(events) {
6329
+ const singleDayEvents = [];
6330
+ const multiDayEvents = [];
6331
+ events.forEach((event) => {
6332
+ const start = parseISO(event.startDate);
6333
+ const end = parseISO(event.endDate);
6334
+ if (isSameDay(start, end)) {
6335
+ singleDayEvents.push(event);
6336
+ } else {
6337
+ multiDayEvents.push(event);
6338
+ }
6339
+ });
6340
+ return { singleDayEvents, multiDayEvents };
6341
+ }
6342
+ function isMultiDayEvent(event) {
6343
+ const start = parseISO(event.startDate);
6344
+ const end = parseISO(event.endDate);
6345
+ return !isSameDay(start, end);
6346
+ }
6347
+ function getEventDuration(event) {
6348
+ const start = parseISO(event.startDate);
6349
+ const end = parseISO(event.endDate);
6350
+ return differenceInDays(end, start) + 1;
6351
+ }
6352
+ function getEventDurationMinutes(event) {
6353
+ const start = parseISO(event.startDate);
6354
+ const end = parseISO(event.endDate);
6355
+ return differenceInMinutes(end, start);
6356
+ }
6357
+ function sortEvents(events) {
6358
+ return [...events].sort((a, b) => {
6359
+ const startDiff = parseISO(a.startDate).getTime() - parseISO(b.startDate).getTime();
6360
+ if (startDiff !== 0) return startDiff;
6361
+ return getEventDuration(b) - getEventDuration(a);
6362
+ });
6363
+ }
6364
+ function getTimePosition(event, visibleHoursRange) {
6365
+ const start = parseISO(event.startDate);
6366
+ const hours = getHours(start);
6367
+ const minutes = getMinutes(start);
6368
+ const startHour = visibleHoursRange?.from ?? 0;
6369
+ const totalMinutes = (hours - startHour) * 60 + minutes;
6370
+ const totalDayMinutes = ((visibleHoursRange?.to ?? 24) - startHour) * 60;
6371
+ return totalMinutes / totalDayMinutes * 100;
6372
+ }
6373
+ function getTimeHeight(event, visibleHoursRange) {
6374
+ const duration = getEventDurationMinutes(event);
6375
+ const totalDayMinutes = ((visibleHoursRange?.to ?? 24) - (visibleHoursRange?.from ?? 0)) * 60;
6376
+ return Math.min(duration / totalDayMinutes * 100, 100);
6377
+ }
6378
+ function formatTime(date, use24h = false) {
6379
+ return format(date, use24h ? "HH:mm" : "h:mm a");
6380
+ }
6381
+ function getWeekDayNames(weekStartsOn = 0, shortNames = true) {
6382
+ const days = [
6383
+ "Sunday",
6384
+ "Monday",
6385
+ "Tuesday",
6386
+ "Wednesday",
6387
+ "Thursday",
6388
+ "Friday",
6389
+ "Saturday"
6390
+ ];
6391
+ const rotated = [...days.slice(weekStartsOn), ...days.slice(0, weekStartsOn)];
6392
+ return shortNames ? rotated.map((d) => d.slice(0, 3)) : rotated;
6393
+ }
6394
+ function getHeaderLabel(date, view) {
6395
+ switch (view) {
6396
+ case "day":
6397
+ return format(date, "EEEE, MMMM d, yyyy");
6398
+ case "week":
6399
+ const weekStart = startOfWeek(date);
6400
+ const weekEnd = endOfWeek(date);
6401
+ if (weekStart.getMonth() === weekEnd.getMonth()) {
6402
+ return format(weekStart, "MMMM d") + " - " + format(weekEnd, "d, yyyy");
6403
+ }
6404
+ return format(weekStart, "MMM d") + " - " + format(weekEnd, "MMM d, yyyy");
6405
+ case "month":
6406
+ return format(date, "MMMM yyyy");
6407
+ case "year":
6408
+ return format(date, "yyyy");
6409
+ case "agenda":
6410
+ return format(date, "MMMM yyyy");
6411
+ default:
6412
+ return format(date, "MMMM yyyy");
6413
+ }
6414
+ }
6415
+ function getViewDateRange(date, view) {
6416
+ switch (view) {
6417
+ case "day":
6418
+ return { start: startOfDay(date), end: endOfDay(date) };
6419
+ case "week":
6420
+ return { start: startOfWeek(date), end: endOfWeek(date) };
6421
+ case "month":
6422
+ return { start: startOfMonth(date), end: endOfMonth(date) };
6423
+ case "year":
6424
+ return { start: startOfYear(date), end: endOfYear(date) };
6425
+ case "agenda":
6426
+ return { start: startOfMonth(date), end: endOfMonth(date) };
6427
+ default:
6428
+ return { start: startOfMonth(date), end: endOfMonth(date) };
6429
+ }
6430
+ }
6431
+ function formatDateRange(start, end) {
6432
+ if (isSameDay(start, end)) {
6433
+ return format(start, "MMM d, yyyy");
6434
+ }
6435
+ if (start.getFullYear() === end.getFullYear()) {
6436
+ if (start.getMonth() === end.getMonth()) {
6437
+ return format(start, "MMM d") + " - " + format(end, "d, yyyy");
6438
+ }
6439
+ return format(start, "MMM d") + " - " + format(end, "MMM d, yyyy");
6440
+ }
6441
+ return format(start, "MMM d, yyyy") + " - " + format(end, "MMM d, yyyy");
6442
+ }
6443
+ function createDefaultEvent(startDate, duration = 60) {
6444
+ return {
6445
+ title: "",
6446
+ description: "",
6447
+ startDate: startDate.toISOString(),
6448
+ endDate: addMinutes(startDate, duration).toISOString(),
6449
+ color: "blue",
6450
+ user: {
6451
+ id: "",
6452
+ name: ""
6453
+ }
6454
+ };
6455
+ }
6456
+ function generateEventId() {
6457
+ return `event_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
6458
+ }
6459
+ function calculateDropDates(event, newStartDate) {
6460
+ const originalStart = parseISO(event.startDate);
6461
+ const originalEnd = parseISO(event.endDate);
6462
+ const duration = differenceInMinutes(originalEnd, originalStart);
6463
+ const newStart = newStartDate;
6464
+ const newEnd = addMinutes(newStart, duration);
6465
+ return {
6466
+ startDate: newStart.toISOString(),
6467
+ endDate: newEnd.toISOString()
6468
+ };
6469
+ }
6470
+ function snapToInterval(date, intervalMinutes = 15) {
6471
+ const minutes = getMinutes(date);
6472
+ const snappedMinutes = Math.round(minutes / intervalMinutes) * intervalMinutes;
6473
+ return setMinutes(date, snappedMinutes);
6474
+ }
6475
+ var colorClasses = {
6476
+ blue: {
6477
+ dot: "bg-blue-500",
6478
+ bg: "bg-blue-50 dark:bg-blue-950/50",
6479
+ text: "text-blue-600 dark:text-blue-400",
6480
+ border: "border-l-blue-500",
6481
+ solid: "bg-blue-500"
6482
+ },
6483
+ green: {
6484
+ dot: "bg-green-500",
6485
+ bg: "bg-green-50 dark:bg-green-950/50",
6486
+ text: "text-green-600 dark:text-green-400",
6487
+ border: "border-l-green-500",
6488
+ solid: "bg-green-500"
6489
+ },
6490
+ red: {
6491
+ dot: "bg-red-500",
6492
+ bg: "bg-red-50 dark:bg-red-950/50",
6493
+ text: "text-red-600 dark:text-red-400",
6494
+ border: "border-l-red-500",
6495
+ solid: "bg-red-500"
6496
+ },
6497
+ yellow: {
6498
+ dot: "bg-yellow-500",
6499
+ bg: "bg-yellow-50 dark:bg-yellow-950/50",
6500
+ text: "text-yellow-600 dark:text-yellow-400",
6501
+ border: "border-l-yellow-500",
6502
+ solid: "bg-yellow-500"
6503
+ },
6504
+ purple: {
6505
+ dot: "bg-purple-500",
6506
+ bg: "bg-purple-50 dark:bg-purple-950/50",
6507
+ text: "text-purple-600 dark:text-purple-400",
6508
+ border: "border-l-purple-500",
6509
+ solid: "bg-purple-500"
6510
+ },
6511
+ orange: {
6512
+ dot: "bg-primary",
6513
+ bg: "bg-orange-50 dark:bg-orange-950/50",
6514
+ text: "text-primary dark:text-orange-400",
6515
+ border: "border-l-primary",
6516
+ solid: "bg-primary"
6517
+ }
6518
+ };
6519
+ function EventBadge({
6520
+ event,
6521
+ variant = "colored",
6522
+ className,
6523
+ showTime = false,
6524
+ compact = false,
6525
+ isDragging = false,
6526
+ onClick
6527
+ }) {
6528
+ const colors = colorClasses[event.color];
6529
+ const startTime = format(parseISO(event.startDate), "h:mm a");
6530
+ const handleClick = (e) => {
6531
+ e.stopPropagation();
6532
+ onClick?.(event, e);
6533
+ };
6534
+ if (variant === "dot") {
6535
+ return /* @__PURE__ */ jsxs(
6536
+ "button",
6537
+ {
6538
+ type: "button",
6539
+ onClick: handleClick,
6540
+ className: cn(
6541
+ "flex items-center gap-1.5 rounded-sm px-1.5 py-0.5 text-left text-xs transition-colors",
6542
+ "hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6543
+ isDragging && "opacity-50",
6544
+ className
6545
+ ),
6546
+ children: [
6547
+ /* @__PURE__ */ jsx("span", { className: cn("size-2 shrink-0 rounded-full", colors.dot) }),
6548
+ /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: event.title }),
6549
+ showTime && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: startTime })
6550
+ ]
6551
+ }
6552
+ );
6553
+ }
6554
+ if (variant === "mixed") {
6555
+ return /* @__PURE__ */ jsxs(
6556
+ "button",
6557
+ {
6558
+ type: "button",
6559
+ onClick: handleClick,
6560
+ className: cn(
6561
+ "flex items-center gap-1.5 rounded-sm border-l-2 px-1.5 py-0.5 text-left text-xs transition-colors",
6562
+ "hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6563
+ colors.border,
6564
+ isDragging && "opacity-50",
6565
+ className
6566
+ ),
6567
+ children: [
6568
+ /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: event.title }),
6569
+ showTime && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: startTime })
6570
+ ]
6571
+ }
6572
+ );
6573
+ }
6574
+ return /* @__PURE__ */ jsxs(
6575
+ "button",
6576
+ {
6577
+ type: "button",
6578
+ onClick: handleClick,
6579
+ className: cn(
6580
+ "flex flex-col items-start rounded-sm border-l-[3px] text-left text-xs transition-colors",
6581
+ "hover:opacity-80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6582
+ colors.border,
6583
+ colors.bg,
6584
+ colors.text,
6585
+ compact ? "px-1.5 py-0.5" : "px-2 py-1",
6586
+ isDragging && "opacity-50 shadow-lg",
6587
+ className
6588
+ ),
6589
+ children: [
6590
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium max-w-full", children: event.title }),
6591
+ showTime && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: startTime })
6592
+ ]
6593
+ }
6594
+ );
6595
+ }
6596
+ function MoreEvents({ count, onClick, className }) {
6597
+ return /* @__PURE__ */ jsxs(
6598
+ "button",
6599
+ {
6600
+ type: "button",
6601
+ onClick,
6602
+ className: cn(
6603
+ "w-full rounded-sm px-2 py-0.5 text-left text-xs text-muted-foreground transition-colors",
6604
+ "hover:bg-muted hover:text-foreground",
6605
+ className
6606
+ ),
6607
+ children: [
6608
+ count,
6609
+ " more..."
6610
+ ]
6611
+ }
6612
+ );
6613
+ }
6614
+ function TimeIndicator({ className }) {
6615
+ const [now, setNow] = React15.useState(/* @__PURE__ */ new Date());
6616
+ React15.useEffect(() => {
6617
+ const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
6618
+ return () => clearInterval(interval);
6619
+ }, []);
6620
+ const hours = now.getHours();
6621
+ const minutes = now.getMinutes();
6622
+ const topPercent = (hours * 60 + minutes) / (24 * 60) * 100;
6623
+ return /* @__PURE__ */ jsxs(
6624
+ "div",
6625
+ {
6626
+ className: cn(
6627
+ "pointer-events-none absolute left-0 right-0 z-20 flex items-center",
6628
+ className
6629
+ ),
6630
+ style: { top: `${topPercent}%` },
6631
+ children: [
6632
+ /* @__PURE__ */ jsx("div", { className: "size-2.5 -translate-x-1/2 rounded-full bg-red-500" }),
6633
+ /* @__PURE__ */ jsx("div", { className: "h-0.5 flex-1 bg-red-500" })
6634
+ ]
6635
+ }
6636
+ );
6637
+ }
6638
+ function DateBadge({ date, className }) {
6639
+ return /* @__PURE__ */ jsxs(
6640
+ "div",
6641
+ {
6642
+ className: cn(
6643
+ "flex flex-col w-14 overflow-hidden border border-border rounded-md",
6644
+ className
6645
+ ),
6646
+ children: [
6647
+ /* @__PURE__ */ jsx("div", { className: "bg-foreground text-background text-[10px] font-bold text-center py-1.5 uppercase tracking-wider", children: format(date, "MMM") }),
6648
+ /* @__PURE__ */ jsx("div", { className: "bg-background text-foreground text-2xl font-bold text-center py-2.5", children: format(date, "d") })
6649
+ ]
6650
+ }
6651
+ );
6652
+ }
6653
+ var DragContext = React15.createContext(null);
6654
+ function DragProvider({
6655
+ children,
6656
+ snapMinutes = 15,
6657
+ onDragStart,
6658
+ onDragEnd
6659
+ }) {
6660
+ const [draggedEvent, setDraggedEventState] = React15.useState(null);
6661
+ const [isDragging, setIsDragging] = React15.useState(false);
6662
+ const { updateEvent } = useEventCalendar();
6663
+ const setDraggedEvent = React15.useCallback((event) => {
6664
+ setDraggedEventState(event);
6665
+ setIsDragging(!!event);
6666
+ if (event) {
6667
+ onDragStart?.(event);
6668
+ }
6669
+ }, [onDragStart]);
6670
+ const handleDrop = React15.useCallback((newStartDate) => {
6671
+ if (!draggedEvent) return;
6672
+ const snappedDate = snapToInterval(newStartDate, snapMinutes);
6673
+ const { startDate, endDate } = calculateDropDates(draggedEvent, snappedDate);
6674
+ const updatedEvent = {
6675
+ ...draggedEvent,
6676
+ startDate,
6677
+ endDate
6678
+ };
6679
+ updateEvent(updatedEvent);
6680
+ onDragEnd?.(updatedEvent, new Date(startDate), new Date(endDate));
6681
+ setDraggedEvent(null);
6682
+ }, [draggedEvent, snapMinutes, updateEvent, onDragEnd, setDraggedEvent]);
6683
+ const contextValue = React15.useMemo(
6684
+ () => ({
6685
+ draggedEvent,
6686
+ setDraggedEvent,
6687
+ isDragging
6688
+ }),
6689
+ [draggedEvent, setDraggedEvent, isDragging]
6690
+ );
6691
+ return /* @__PURE__ */ jsx(DragContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(DragDropHandler, { onDrop: handleDrop, children }) });
6692
+ }
6693
+ function useDrag() {
6694
+ const context = React15.useContext(DragContext);
6695
+ if (!context) {
6696
+ throw new Error("useDrag must be used within a DragProvider");
6697
+ }
6698
+ return context;
6699
+ }
6700
+ function DragDropHandler({ children, onDrop }) {
6701
+ return /* @__PURE__ */ jsx(Fragment, { children });
6702
+ }
6703
+ function DraggableEvent({
6704
+ event,
6705
+ children,
6706
+ disabled = false
6707
+ }) {
6708
+ const { setDraggedEvent, isDragging, draggedEvent } = useDrag();
6709
+ const isDragged = draggedEvent?.id === event.id;
6710
+ const handleDragStart = (e) => {
6711
+ if (disabled) return;
6712
+ e.dataTransfer.effectAllowed = "move";
6713
+ e.dataTransfer.setData("text/plain", event.id);
6714
+ setDraggedEvent(event);
6715
+ };
6716
+ const handleDragEnd = () => {
6717
+ setDraggedEvent(null);
6718
+ };
6719
+ return /* @__PURE__ */ jsx(
6720
+ "div",
6721
+ {
6722
+ draggable: !disabled,
6723
+ onDragStart: handleDragStart,
6724
+ onDragEnd: handleDragEnd,
6725
+ className: isDragged ? "opacity-50" : "",
6726
+ style: { cursor: disabled ? "default" : "grab" },
6727
+ children
6728
+ }
6729
+ );
6730
+ }
6731
+ function DroppableZone({
6732
+ date,
6733
+ children,
6734
+ onDrop,
6735
+ className
6736
+ }) {
6737
+ const { draggedEvent, setDraggedEvent } = useDrag();
6738
+ const { updateEvent } = useEventCalendar();
6739
+ const [isOver, setIsOver] = React15.useState(false);
6740
+ const handleDragOver = (e) => {
6741
+ e.preventDefault();
6742
+ e.dataTransfer.dropEffect = "move";
6743
+ setIsOver(true);
6744
+ };
6745
+ const handleDragLeave = () => {
6746
+ setIsOver(false);
6747
+ };
6748
+ const handleDrop = (e) => {
6749
+ e.preventDefault();
6750
+ setIsOver(false);
6751
+ if (!draggedEvent) return;
6752
+ const { startDate, endDate } = calculateDropDates(draggedEvent, date);
6753
+ const updatedEvent = {
6754
+ ...draggedEvent,
6755
+ startDate,
6756
+ endDate
6757
+ };
6758
+ updateEvent(updatedEvent);
6759
+ onDrop?.(updatedEvent, date);
6760
+ setDraggedEvent(null);
6761
+ };
6762
+ return /* @__PURE__ */ jsx(
6763
+ "div",
6764
+ {
6765
+ onDragOver: handleDragOver,
6766
+ onDragLeave: handleDragLeave,
6767
+ onDrop: handleDrop,
6768
+ className,
6769
+ "data-drag-over": isOver,
6770
+ children
6771
+ }
6772
+ );
6773
+ }
6774
+ function useDroppable({ date, hour, minute = 0, onDrop }) {
6775
+ const { draggedEvent, setDraggedEvent } = useDrag();
6776
+ const { updateEvent } = useEventCalendar();
6777
+ const [isOver, setIsOver] = React15.useState(false);
6778
+ const dropTargetDate = React15.useMemo(() => {
6779
+ const targetDate = new Date(date);
6780
+ if (hour !== void 0) {
6781
+ targetDate.setHours(hour, minute, 0, 0);
6782
+ }
6783
+ return targetDate;
6784
+ }, [date, hour, minute]);
6785
+ const handleDragOver = React15.useCallback((e) => {
6786
+ e.preventDefault();
6787
+ e.dataTransfer.dropEffect = "move";
6788
+ if (!isOver) setIsOver(true);
6789
+ }, [isOver]);
6790
+ const handleDragLeave = React15.useCallback(() => {
6791
+ setIsOver(false);
6792
+ }, []);
6793
+ const handleDrop = React15.useCallback((e) => {
6794
+ e.preventDefault();
6795
+ setIsOver(false);
6796
+ if (!draggedEvent) return;
6797
+ const { startDate, endDate } = calculateDropDates(draggedEvent, dropTargetDate);
6798
+ const updatedEvent = {
6799
+ ...draggedEvent,
6800
+ startDate,
6801
+ endDate
6802
+ };
6803
+ updateEvent(updatedEvent);
6804
+ onDrop?.(updatedEvent, dropTargetDate);
6805
+ setDraggedEvent(null);
6806
+ }, [draggedEvent, dropTargetDate, updateEvent, onDrop, setDraggedEvent]);
6807
+ return {
6808
+ isOver,
6809
+ dropProps: {
6810
+ onDragOver: handleDragOver,
6811
+ onDragLeave: handleDragLeave,
6812
+ onDrop: handleDrop,
6813
+ "data-drag-over": isOver
6814
+ }
6815
+ };
6816
+ }
6817
+ function useDraggable(event, disabled = false) {
6818
+ const { setDraggedEvent, draggedEvent } = useDrag();
6819
+ const isDragged = draggedEvent?.id === event.id;
6820
+ const handleDragStart = React15.useCallback((e) => {
6821
+ if (disabled) return;
6822
+ e.dataTransfer.effectAllowed = "move";
6823
+ e.dataTransfer.setData("text/plain", event.id);
6824
+ setDraggedEvent(event);
6825
+ }, [disabled, event, setDraggedEvent]);
6826
+ const handleDragEnd = React15.useCallback(() => {
6827
+ setDraggedEvent(null);
6828
+ }, [setDraggedEvent]);
6829
+ return {
6830
+ isDragged,
6831
+ dragProps: {
6832
+ draggable: !disabled,
6833
+ onDragStart: handleDragStart,
6834
+ onDragEnd: handleDragEnd,
6835
+ style: { cursor: disabled ? "default" : "grab" }
6836
+ }
6837
+ };
6838
+ }
6839
+ var WEEK_DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
6840
+ function DraggableEventWrapper({
6841
+ event,
6842
+ children
6843
+ }) {
6844
+ const { isDragged, dragProps } = useDraggable(event);
6845
+ return /* @__PURE__ */ jsx(
6846
+ "div",
6847
+ {
6848
+ ...dragProps,
6849
+ className: cn(
6850
+ "transition-opacity",
6851
+ isDragged && "opacity-50"
6852
+ ),
6853
+ children
6854
+ }
6855
+ );
6856
+ }
6857
+ function MonthView({
6858
+ className,
6859
+ maxEventsPerDay = 3,
6860
+ weekStartsOn = 0,
6861
+ onEventClick,
6862
+ onDateClick,
6863
+ onMoreClick
6864
+ }) {
6865
+ const { selectedDate, badgeVariant, setSelectedDate, setView } = useEventCalendar();
6866
+ const filteredEvents = useFilteredEvents();
6867
+ const { singleDayEvents, multiDayEvents } = React15.useMemo(
6868
+ () => splitEventsByDuration(filteredEvents),
6869
+ [filteredEvents]
6870
+ );
6871
+ const cells = React15.useMemo(
6872
+ () => getCalendarCells(selectedDate),
6873
+ [selectedDate]
6874
+ );
6875
+ const eventPositions = React15.useMemo(
6876
+ () => calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate),
6877
+ [multiDayEvents, singleDayEvents, selectedDate]
6878
+ );
6879
+ const allEvents = [...multiDayEvents, ...singleDayEvents];
6880
+ const handleDateClick = (date) => {
6881
+ setSelectedDate(date);
6882
+ setView("day");
6883
+ onDateClick?.(date);
6884
+ };
6885
+ const handleMoreClick = (date, events) => {
6886
+ setSelectedDate(date);
6887
+ setView("day");
6888
+ onMoreClick?.(date, events);
6889
+ };
6890
+ return /* @__PURE__ */ jsxs("div", { className: cn("", className), children: [
6891
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 divide-x divide-border/50", children: WEEK_DAYS.map((day) => /* @__PURE__ */ jsx(
6892
+ "div",
6893
+ {
6894
+ className: "flex items-center justify-center py-2",
6895
+ children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: day })
6896
+ },
6897
+ day
6898
+ )) }),
6899
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 overflow-hidden", children: cells.map((cell) => /* @__PURE__ */ jsx(
6900
+ DayCell,
6901
+ {
6902
+ cell,
6903
+ events: allEvents,
6904
+ eventPositions,
6905
+ selectedDate,
6906
+ badgeVariant,
6907
+ maxEvents: maxEventsPerDay,
6908
+ onDateClick: handleDateClick,
6909
+ onEventClick,
6910
+ onMoreClick: handleMoreClick
6911
+ },
6912
+ cell.date.toISOString()
6913
+ )) })
6914
+ ] });
6915
+ }
6916
+ function DayCell({
6917
+ cell,
6918
+ events,
6919
+ eventPositions,
6920
+ selectedDate,
6921
+ badgeVariant,
6922
+ maxEvents,
6923
+ onDateClick,
6924
+ onEventClick,
6925
+ onMoreClick
6926
+ }) {
6927
+ const { date, currentMonth } = cell;
6928
+ const isCurrentDay = isToday(date);
6929
+ const isSelectedDay = isSameDay(date, selectedDate);
6930
+ const { isOver, dropProps } = useDroppable({ date });
6931
+ const cellEvents = getMonthCellEvents(date, events, eventPositions);
6932
+ const positionedEvents = cellEvents.filter((e) => e.position !== -1);
6933
+ const hiddenEvents = cellEvents.filter((e) => e.position === -1);
6934
+ const slots = [null, null, null];
6935
+ positionedEvents.forEach((event) => {
6936
+ if (event.position >= 0 && event.position < 3) {
6937
+ slots[event.position] = event;
6938
+ }
6939
+ });
6940
+ const hiddenCount = hiddenEvents.length + positionedEvents.filter((e) => e.position >= 3).length;
6941
+ const isEventStart = (event) => isSameDay(parseISO(event.startDate), date);
6942
+ return /* @__PURE__ */ jsxs(
6943
+ "div",
6944
+ {
6945
+ ...dropProps,
6946
+ className: cn(
6947
+ "relative min-h-[120px] border-b border-r border-border/50 p-1 transition-colors",
6948
+ !currentMonth && "bg-muted/30",
6949
+ isOver && "bg-primary/10 ring-2 ring-primary/50 ring-inset"
6950
+ ),
6951
+ children: [
6952
+ /* @__PURE__ */ jsx(
6953
+ "button",
6954
+ {
6955
+ type: "button",
6956
+ onClick: () => onDateClick(date),
6957
+ className: cn(
6958
+ "mb-1 flex size-7 items-center justify-center text-sm transition-colors",
6959
+ "hover:bg-muted rounded-sm",
6960
+ isCurrentDay && "bg-primary text-primary-foreground hover:bg-primary/90 rounded-sm",
6961
+ isSelectedDay && !isCurrentDay && "bg-muted font-semibold rounded-sm",
6962
+ !currentMonth && "text-muted-foreground"
6963
+ ),
6964
+ children: cell.day
6965
+ }
6966
+ ),
6967
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
6968
+ slots.map((event, index) => {
6969
+ if (!event) {
6970
+ return /* @__PURE__ */ jsx("div", { className: "h-5" }, `empty-${index}`);
6971
+ }
6972
+ const showTitle = isEventStart(event) || startOfDay(date).getDay() === 0;
6973
+ return /* @__PURE__ */ jsx(DraggableEventWrapper, { event, children: /* @__PURE__ */ jsx(
6974
+ EventBadge,
6975
+ {
6976
+ event,
6977
+ variant: badgeVariant,
6978
+ compact: true,
6979
+ showTime: showTitle,
6980
+ onClick: (e) => onEventClick?.(e),
6981
+ className: cn(
6982
+ "w-full",
6983
+ // If not showing title, make it appear as a continuation
6984
+ !showTitle && "rounded-l-none border-l-0"
6985
+ )
6986
+ }
6987
+ ) }, event.id);
6988
+ }),
6989
+ hiddenCount > 0 && /* @__PURE__ */ jsx(
6990
+ MoreEvents,
6991
+ {
6992
+ count: hiddenCount,
6993
+ onClick: () => onMoreClick(date, cellEvents)
6994
+ }
6995
+ )
6996
+ ] })
6997
+ ]
6998
+ }
6999
+ );
7000
+ }
7001
+ function DraggableEventWrapper2({
7002
+ event,
7003
+ children,
7004
+ className,
7005
+ style
7006
+ }) {
7007
+ const { isDragged, dragProps } = useDraggable(event);
7008
+ return /* @__PURE__ */ jsx(
7009
+ "div",
7010
+ {
7011
+ ...dragProps,
7012
+ className: cn(
7013
+ className,
7014
+ "transition-opacity",
7015
+ isDragged && "opacity-50"
7016
+ ),
7017
+ style,
7018
+ children
7019
+ }
7020
+ );
7021
+ }
7022
+ function DroppableTimeSlot({
7023
+ date,
7024
+ hour,
7025
+ minute,
7026
+ className,
7027
+ onClick
7028
+ }) {
7029
+ const { isOver, dropProps } = useDroppable({ date, hour, minute });
7030
+ return /* @__PURE__ */ jsx(
7031
+ "div",
7032
+ {
7033
+ ...dropProps,
7034
+ onClick,
7035
+ className: cn(
7036
+ className,
7037
+ "cursor-pointer transition-colors hover:bg-accent",
7038
+ isOver && "bg-primary/20"
7039
+ )
7040
+ }
7041
+ );
7042
+ }
7043
+ function WeekView({
7044
+ className,
7045
+ weekStartsOn = 0,
7046
+ onEventClick,
7047
+ onDateClick,
7048
+ onTimeClick
7049
+ }) {
7050
+ const {
7051
+ selectedDate,
7052
+ badgeVariant,
7053
+ workingHours,
7054
+ visibleHours
7055
+ } = useEventCalendar();
7056
+ const filteredEvents = useFilteredEvents();
7057
+ const { singleDayEvents, multiDayEvents } = React15.useMemo(
7058
+ () => splitEventsByDuration(filteredEvents),
7059
+ [filteredEvents]
7060
+ );
7061
+ const { hours, earliestEventHour, latestEventHour } = getVisibleHours(
7062
+ visibleHours,
7063
+ singleDayEvents
7064
+ );
7065
+ const weekStart = startOfWeek(selectedDate, { weekStartsOn });
7066
+ const weekDays = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
7067
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7068
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center border-b py-4 text-sm text-muted-foreground sm:hidden", children: [
7069
+ /* @__PURE__ */ jsx("p", { children: "Weekly view is not available on smaller devices." }),
7070
+ /* @__PURE__ */ jsx("p", { children: "Please switch to daily or monthly view." })
7071
+ ] }),
7072
+ /* @__PURE__ */ jsxs("div", { className: cn("hidden flex-col sm:flex", className), children: [
7073
+ /* @__PURE__ */ jsx(
7074
+ WeekViewMultiDayEventsRow,
7075
+ {
7076
+ selectedDate,
7077
+ multiDayEvents
7078
+ }
7079
+ ),
7080
+ /* @__PURE__ */ jsxs("div", { className: "relative z-20 flex border-b border-border/50", children: [
7081
+ /* @__PURE__ */ jsx("div", { className: "w-18" }),
7082
+ /* @__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(
7083
+ "span",
7084
+ {
7085
+ className: "py-2 text-center text-xs font-medium text-muted-foreground",
7086
+ children: [
7087
+ format(day, "EE"),
7088
+ " ",
7089
+ /* @__PURE__ */ jsx("span", { className: "ml-1 font-semibold text-foreground", children: format(day, "d") })
7090
+ ]
7091
+ },
7092
+ index
7093
+ )) })
7094
+ ] }),
7095
+ /* @__PURE__ */ jsx(ScrollArea, { className: "h-[736px]", type: "always", children: /* @__PURE__ */ jsxs("div", { className: "flex overflow-hidden", children: [
7096
+ /* @__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)) }),
7097
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 border-l border-border/50", children: [
7098
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 divide-x divide-border/50", children: weekDays.map((day, dayIndex) => {
7099
+ const dayEvents = singleDayEvents.filter(
7100
+ (event) => isSameDay(parseISO(event.startDate), day) || isSameDay(parseISO(event.endDate), day)
7101
+ );
7102
+ const groupedEvents = groupEvents(dayEvents);
7103
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
7104
+ hours.map((hour, index) => {
7105
+ const isDisabled = !isWorkingHour(day, hour, workingHours);
7106
+ return /* @__PURE__ */ jsxs(
7107
+ "div",
7108
+ {
7109
+ className: cn(
7110
+ "relative",
7111
+ 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)]"
7112
+ ),
7113
+ style: { height: "96px" },
7114
+ children: [
7115
+ index !== 0 && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 border-b border-border/40" }),
7116
+ /* @__PURE__ */ jsx(
7117
+ DroppableTimeSlot,
7118
+ {
7119
+ date: day,
7120
+ hour,
7121
+ minute: 0,
7122
+ className: "absolute inset-x-0 top-0 h-[24px]",
7123
+ onClick: () => onTimeClick?.(day, hour, 0)
7124
+ }
7125
+ ),
7126
+ /* @__PURE__ */ jsx(
7127
+ DroppableTimeSlot,
7128
+ {
7129
+ date: day,
7130
+ hour,
7131
+ minute: 15,
7132
+ className: "absolute inset-x-0 top-[24px] h-[24px]",
7133
+ onClick: () => onTimeClick?.(day, hour, 15)
7134
+ }
7135
+ ),
7136
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-1/2 border-b border-dashed border-border/30" }),
7137
+ /* @__PURE__ */ jsx(
7138
+ DroppableTimeSlot,
7139
+ {
7140
+ date: day,
7141
+ hour,
7142
+ minute: 30,
7143
+ className: "absolute inset-x-0 top-[48px] h-[24px]",
7144
+ onClick: () => onTimeClick?.(day, hour, 30)
7145
+ }
7146
+ ),
7147
+ /* @__PURE__ */ jsx(
7148
+ DroppableTimeSlot,
7149
+ {
7150
+ date: day,
7151
+ hour,
7152
+ minute: 45,
7153
+ className: "absolute inset-x-0 top-[72px] h-[24px]",
7154
+ onClick: () => onTimeClick?.(day, hour, 45)
7155
+ }
7156
+ )
7157
+ ]
7158
+ },
7159
+ hour
7160
+ );
7161
+ }),
7162
+ groupedEvents.map(
7163
+ (group, groupIndex) => group.map((event) => {
7164
+ let style = getEventBlockStyle(
7165
+ event,
7166
+ day,
7167
+ groupIndex,
7168
+ groupedEvents.length,
7169
+ { from: earliestEventHour}
7170
+ );
7171
+ const hasOverlap = groupedEvents.some(
7172
+ (otherGroup, otherIndex) => otherIndex !== groupIndex && otherGroup.some(
7173
+ (otherEvent) => areIntervalsOverlapping(
7174
+ {
7175
+ start: parseISO(event.startDate),
7176
+ end: parseISO(event.endDate)
7177
+ },
7178
+ {
7179
+ start: parseISO(otherEvent.startDate),
7180
+ end: parseISO(otherEvent.endDate)
7181
+ }
7182
+ )
7183
+ )
7184
+ );
7185
+ if (!hasOverlap) {
7186
+ style = { ...style, width: "100%", left: "0%" };
7187
+ }
7188
+ return /* @__PURE__ */ jsx(
7189
+ DraggableEventWrapper2,
7190
+ {
7191
+ event,
7192
+ className: "absolute px-0.5 py-0.5",
7193
+ style,
7194
+ children: /* @__PURE__ */ jsx(
7195
+ EventBadge,
7196
+ {
7197
+ event,
7198
+ variant: badgeVariant,
7199
+ showTime: true,
7200
+ onClick: (e) => onEventClick?.(e),
7201
+ className: "h-full w-full"
7202
+ }
7203
+ )
7204
+ },
7205
+ event.id
7206
+ );
7207
+ })
7208
+ )
7209
+ ] }, dayIndex);
7210
+ }) }),
7211
+ weekDays.some((day) => isToday(day)) && /* @__PURE__ */ jsx(
7212
+ CalendarTimeline,
7213
+ {
7214
+ firstVisibleHour: earliestEventHour,
7215
+ lastVisibleHour: latestEventHour
7216
+ }
7217
+ )
7218
+ ] })
7219
+ ] }) })
7220
+ ] })
7221
+ ] });
7222
+ }
7223
+ function WeekViewMultiDayEventsRow({
7224
+ selectedDate,
7225
+ multiDayEvents
7226
+ }) {
7227
+ const { badgeVariant } = useEventCalendar();
7228
+ if (multiDayEvents.length === 0) return null;
7229
+ const weekStart = startOfWeek(selectedDate);
7230
+ const weekDays = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
7231
+ return /* @__PURE__ */ jsxs("div", { className: "hidden border-b sm:flex", children: [
7232
+ /* @__PURE__ */ jsx("div", { className: "w-18 shrink-0" }),
7233
+ /* @__PURE__ */ jsx("div", { className: "grid flex-1 grid-cols-7 divide-x border-l", children: weekDays.map((day, index) => {
7234
+ const dayMultiEvents = multiDayEvents.filter((event) => {
7235
+ const start = parseISO(event.startDate);
7236
+ const end = parseISO(event.endDate);
7237
+ return day >= start && day <= end;
7238
+ });
7239
+ return /* @__PURE__ */ jsxs("div", { className: "min-h-[32px] space-y-1 p-1", children: [
7240
+ dayMultiEvents.slice(0, 2).map((event) => /* @__PURE__ */ jsx(
7241
+ EventBadge,
7242
+ {
7243
+ event,
7244
+ variant: badgeVariant,
7245
+ compact: true,
7246
+ className: "w-full"
7247
+ },
7248
+ event.id
7249
+ )),
7250
+ dayMultiEvents.length > 2 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground text-center", children: [
7251
+ "+",
7252
+ dayMultiEvents.length - 2,
7253
+ " more"
7254
+ ] })
7255
+ ] }, index);
7256
+ }) })
7257
+ ] });
7258
+ }
7259
+ function CalendarTimeline({
7260
+ firstVisibleHour,
7261
+ lastVisibleHour
7262
+ }) {
7263
+ const [currentTime, setCurrentTime] = React15.useState(/* @__PURE__ */ new Date());
7264
+ React15.useEffect(() => {
7265
+ const interval = setInterval(() => {
7266
+ setCurrentTime(/* @__PURE__ */ new Date());
7267
+ }, 6e4);
7268
+ return () => clearInterval(interval);
7269
+ }, []);
7270
+ const currentHour = currentTime.getHours();
7271
+ const currentMinute = currentTime.getMinutes();
7272
+ if (currentHour < firstVisibleHour || currentHour >= lastVisibleHour) {
7273
+ return null;
7274
+ }
7275
+ const minutesSinceStart = (currentHour - firstVisibleHour) * 60 + currentMinute;
7276
+ const totalMinutes = (lastVisibleHour - firstVisibleHour) * 60;
7277
+ const topPercent = minutesSinceStart / totalMinutes * 100;
7278
+ return /* @__PURE__ */ jsxs(
7279
+ "div",
7280
+ {
7281
+ className: "pointer-events-none absolute inset-x-0 z-30 flex items-center",
7282
+ style: { top: `${topPercent}%` },
7283
+ children: [
7284
+ /* @__PURE__ */ jsx("div", { className: "size-3 -translate-x-1/2 rounded-full bg-red-500" }),
7285
+ /* @__PURE__ */ jsx("div", { className: "h-0.5 flex-1 bg-red-500" })
7286
+ ]
7287
+ }
7288
+ );
7289
+ }
7290
+ function DraggableEventWrapper3({
7291
+ event,
7292
+ children,
7293
+ className,
7294
+ style
7295
+ }) {
7296
+ const { isDragged, dragProps } = useDraggable(event);
7297
+ return /* @__PURE__ */ jsx(
7298
+ "div",
7299
+ {
7300
+ ...dragProps,
7301
+ className: cn(
7302
+ className,
7303
+ "transition-opacity",
7304
+ isDragged && "opacity-50"
7305
+ ),
7306
+ style,
7307
+ children
7308
+ }
7309
+ );
7310
+ }
7311
+ function DroppableTimeSlot2({
7312
+ date,
7313
+ hour,
7314
+ minute,
7315
+ className,
7316
+ onClick
7317
+ }) {
7318
+ const { isOver, dropProps } = useDroppable({ date, hour, minute });
7319
+ return /* @__PURE__ */ jsx(
7320
+ "div",
7321
+ {
7322
+ ...dropProps,
7323
+ onClick,
7324
+ className: cn(
7325
+ className,
7326
+ "cursor-pointer transition-colors hover:bg-accent",
7327
+ isOver && "bg-primary/20"
7328
+ )
7329
+ }
7330
+ );
7331
+ }
7332
+ function DayView({
7333
+ className,
7334
+ showSidebar = true,
7335
+ onEventClick,
7336
+ onTimeClick
7337
+ }) {
7338
+ const {
7339
+ selectedDate,
7340
+ setSelectedDate,
7341
+ badgeVariant,
7342
+ users,
7343
+ workingHours,
7344
+ visibleHours
7345
+ } = useEventCalendar();
7346
+ const filteredEvents = useFilteredEvents();
7347
+ const { singleDayEvents, multiDayEvents } = React15.useMemo(
7348
+ () => splitEventsByDuration(filteredEvents),
7349
+ [filteredEvents]
7350
+ );
7351
+ const { hours, earliestEventHour, latestEventHour } = getVisibleHours(
7352
+ visibleHours,
7353
+ singleDayEvents
7354
+ );
7355
+ const currentEvents = React15.useMemo(() => {
7356
+ if (!isToday(selectedDate)) return [];
7357
+ return getCurrentEvents(singleDayEvents);
7358
+ }, [singleDayEvents, selectedDate]);
7359
+ const dayEvents = singleDayEvents.filter((event) => {
7360
+ const eventDate = parseISO(event.startDate);
7361
+ return eventDate.getDate() === selectedDate.getDate() && eventDate.getMonth() === selectedDate.getMonth() && eventDate.getFullYear() === selectedDate.getFullYear();
7362
+ });
7363
+ const groupedEvents = groupEvents(dayEvents);
7364
+ const handleDateSelect = (date) => {
7365
+ if (date) {
7366
+ setSelectedDate(date);
7367
+ }
7368
+ };
7369
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex", className), children: [
7370
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col", children: [
7371
+ multiDayEvents.length > 0 && /* @__PURE__ */ jsx(
7372
+ DayViewMultiDayEventsRow,
7373
+ {
7374
+ selectedDate,
7375
+ multiDayEvents
7376
+ }
7377
+ ),
7378
+ /* @__PURE__ */ jsxs("div", { className: "relative z-20 flex border-b border-border/50", children: [
7379
+ /* @__PURE__ */ jsx("div", { className: "w-18" }),
7380
+ /* @__PURE__ */ jsxs("span", { className: "flex-1 border-l border-border/50 py-2 text-center text-xs font-medium text-muted-foreground", children: [
7381
+ format(selectedDate, "EE"),
7382
+ " ",
7383
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: format(selectedDate, "d") })
7384
+ ] })
7385
+ ] }),
7386
+ /* @__PURE__ */ jsx(ScrollArea, { className: "h-[800px]", type: "always", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
7387
+ /* @__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)) }),
7388
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1 border-l border-border/50", children: [
7389
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
7390
+ hours.map((hour, index) => {
7391
+ const isDisabled = !isWorkingHour(selectedDate, hour, workingHours);
7392
+ return /* @__PURE__ */ jsxs(
7393
+ "div",
7394
+ {
7395
+ className: cn(
7396
+ "relative",
7397
+ 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)]"
7398
+ ),
7399
+ style: { height: "96px" },
7400
+ children: [
7401
+ index !== 0 && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 border-b border-border/40" }),
7402
+ /* @__PURE__ */ jsx(
7403
+ DroppableTimeSlot2,
7404
+ {
7405
+ date: selectedDate,
7406
+ hour,
7407
+ minute: 0,
7408
+ className: "absolute inset-x-0 top-0 h-[24px]",
7409
+ onClick: () => onTimeClick?.(selectedDate, hour, 0)
7410
+ }
7411
+ ),
7412
+ /* @__PURE__ */ jsx(
7413
+ DroppableTimeSlot2,
7414
+ {
7415
+ date: selectedDate,
7416
+ hour,
7417
+ minute: 15,
7418
+ className: "absolute inset-x-0 top-[24px] h-[24px]",
7419
+ onClick: () => onTimeClick?.(selectedDate, hour, 15)
7420
+ }
7421
+ ),
7422
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-1/2 border-b border-dashed border-border/30" }),
7423
+ /* @__PURE__ */ jsx(
7424
+ DroppableTimeSlot2,
7425
+ {
7426
+ date: selectedDate,
7427
+ hour,
7428
+ minute: 30,
7429
+ className: "absolute inset-x-0 top-[48px] h-[24px]",
7430
+ onClick: () => onTimeClick?.(selectedDate, hour, 30)
7431
+ }
7432
+ ),
7433
+ /* @__PURE__ */ jsx(
7434
+ DroppableTimeSlot2,
7435
+ {
7436
+ date: selectedDate,
7437
+ hour,
7438
+ minute: 45,
7439
+ className: "absolute inset-x-0 top-[72px] h-[24px]",
7440
+ onClick: () => onTimeClick?.(selectedDate, hour, 45)
7441
+ }
7442
+ )
7443
+ ]
7444
+ },
7445
+ hour
7446
+ );
7447
+ }),
7448
+ groupedEvents.map(
7449
+ (group, groupIndex) => group.map((event) => {
7450
+ let style = getEventBlockStyle(
7451
+ event,
7452
+ selectedDate,
7453
+ groupIndex,
7454
+ groupedEvents.length,
7455
+ { from: earliestEventHour}
7456
+ );
7457
+ const hasOverlap = groupedEvents.some(
7458
+ (otherGroup, otherIndex) => otherIndex !== groupIndex && otherGroup.some(
7459
+ (otherEvent) => areIntervalsOverlapping(
7460
+ {
7461
+ start: parseISO(event.startDate),
7462
+ end: parseISO(event.endDate)
7463
+ },
7464
+ {
7465
+ start: parseISO(otherEvent.startDate),
7466
+ end: parseISO(otherEvent.endDate)
7467
+ }
7468
+ )
7469
+ )
7470
+ );
7471
+ if (!hasOverlap) {
7472
+ style = { ...style, width: "100%", left: "0%" };
7473
+ }
7474
+ return /* @__PURE__ */ jsx(
7475
+ DraggableEventWrapper3,
7476
+ {
7477
+ event,
7478
+ className: "absolute px-1 py-0.5",
7479
+ style,
7480
+ children: /* @__PURE__ */ jsx(
7481
+ EventBadge,
7482
+ {
7483
+ event,
7484
+ variant: badgeVariant,
7485
+ showTime: true,
7486
+ onClick: (e) => onEventClick?.(e),
7487
+ className: "h-full w-full"
7488
+ }
7489
+ )
7490
+ },
7491
+ event.id
7492
+ );
7493
+ })
7494
+ )
7495
+ ] }),
7496
+ isToday(selectedDate) && /* @__PURE__ */ jsx(
7497
+ CalendarTimeline2,
7498
+ {
7499
+ firstVisibleHour: earliestEventHour,
7500
+ lastVisibleHour: latestEventHour
7501
+ }
7502
+ )
7503
+ ] })
7504
+ ] }) })
7505
+ ] }),
7506
+ showSidebar && /* @__PURE__ */ jsxs("div", { className: "hidden w-64 divide-y border-l md:block", children: [
7507
+ /* @__PURE__ */ jsx(
7508
+ Calendar,
7509
+ {
7510
+ className: "mx-auto w-fit",
7511
+ mode: "single",
7512
+ selected: selectedDate,
7513
+ onSelect: handleDateSelect
7514
+ }
7515
+ ),
7516
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-3", children: [
7517
+ currentEvents.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 px-4 pt-4", children: [
7518
+ /* @__PURE__ */ jsxs("span", { className: "relative mt-[5px] flex size-2.5", children: [
7519
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex size-full animate-ping rounded-full bg-green-400 opacity-75" }),
7520
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex size-2.5 rounded-full bg-green-600" })
7521
+ ] }),
7522
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Happening now" })
7523
+ ] }) : /* @__PURE__ */ jsx("p", { className: "p-4 text-center text-sm italic text-muted-foreground", children: "No appointments or consultations at the moment" }),
7524
+ 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) => {
7525
+ const user = users.find((u) => u.id === event.user.id);
7526
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
7527
+ /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm font-semibold", children: event.title }),
7528
+ user && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
7529
+ /* @__PURE__ */ jsx(User, { className: "size-3.5" }),
7530
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: user.name })
7531
+ ] }),
7532
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
7533
+ /* @__PURE__ */ jsx(Calendar$1, { className: "size-3.5" }),
7534
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: format(/* @__PURE__ */ new Date(), "MMM d, yyyy") })
7535
+ ] }),
7536
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
7537
+ /* @__PURE__ */ jsx(Clock, { className: "size-3.5" }),
7538
+ /* @__PURE__ */ jsxs("span", { className: "text-sm", children: [
7539
+ format(parseISO(event.startDate), "h:mm a"),
7540
+ " -",
7541
+ " ",
7542
+ format(parseISO(event.endDate), "h:mm a")
7543
+ ] })
7544
+ ] })
7545
+ ] }, event.id);
7546
+ }) }) })
7547
+ ] })
7548
+ ] })
7549
+ ] });
7550
+ }
7551
+ function DayViewMultiDayEventsRow({
7552
+ selectedDate,
7553
+ multiDayEvents
7554
+ }) {
7555
+ const { badgeVariant } = useEventCalendar();
7556
+ const relevantEvents = multiDayEvents.filter((event) => {
7557
+ const start = parseISO(event.startDate);
7558
+ const end = parseISO(event.endDate);
7559
+ return selectedDate >= start && selectedDate <= end;
7560
+ });
7561
+ if (relevantEvents.length === 0) return null;
7562
+ return /* @__PURE__ */ jsxs("div", { className: "flex border-b", children: [
7563
+ /* @__PURE__ */ jsx("div", { className: "w-18 shrink-0" }),
7564
+ /* @__PURE__ */ jsx("div", { className: "flex-1 space-y-1 border-l p-2", children: relevantEvents.map((event) => /* @__PURE__ */ jsx(
7565
+ EventBadge,
7566
+ {
7567
+ event,
7568
+ variant: badgeVariant,
7569
+ className: "w-full"
7570
+ },
7571
+ event.id
7572
+ )) })
7573
+ ] });
7574
+ }
7575
+ function CalendarTimeline2({
7576
+ firstVisibleHour,
7577
+ lastVisibleHour
7578
+ }) {
7579
+ const [currentTime, setCurrentTime] = React15.useState(/* @__PURE__ */ new Date());
7580
+ React15.useEffect(() => {
7581
+ const interval = setInterval(() => {
7582
+ setCurrentTime(/* @__PURE__ */ new Date());
7583
+ }, 6e4);
7584
+ return () => clearInterval(interval);
7585
+ }, []);
7586
+ const currentHour = currentTime.getHours();
7587
+ const currentMinute = currentTime.getMinutes();
7588
+ if (currentHour < firstVisibleHour || currentHour >= lastVisibleHour) {
7589
+ return null;
7590
+ }
7591
+ const minutesSinceStart = (currentHour - firstVisibleHour) * 60 + currentMinute;
7592
+ const totalMinutes = (lastVisibleHour - firstVisibleHour) * 60;
7593
+ const topPercent = minutesSinceStart / totalMinutes * 100;
7594
+ return /* @__PURE__ */ jsxs(
7595
+ "div",
7596
+ {
7597
+ className: "pointer-events-none absolute inset-x-0 z-30 flex items-center",
7598
+ style: { top: `${topPercent}%` },
7599
+ children: [
7600
+ /* @__PURE__ */ jsx("div", { className: "size-3 -translate-x-1/2 rounded-full bg-red-500" }),
7601
+ /* @__PURE__ */ jsx("div", { className: "h-0.5 flex-1 bg-red-500" })
7602
+ ]
7603
+ }
7604
+ );
7605
+ }
7606
+ function YearView({
7607
+ className,
7608
+ weekStartsOn = 0,
7609
+ onMonthClick,
7610
+ onDateClick
7611
+ }) {
7612
+ const { selectedDate, setSelectedDate, setView } = useEventCalendar();
7613
+ const filteredEvents = useFilteredEvents();
7614
+ const months = React15.useMemo(() => {
7615
+ const yearStart = startOfYear(selectedDate);
7616
+ return Array.from({ length: 12 }, (_, i) => addMonths(yearStart, i));
7617
+ }, [selectedDate]);
7618
+ const handleMonthClick = (date) => {
7619
+ setSelectedDate(date);
7620
+ setView("month");
7621
+ onMonthClick?.(date);
7622
+ };
7623
+ const handleDateClick = (date) => {
7624
+ setSelectedDate(date);
7625
+ setView("day");
7626
+ onDateClick?.(date);
7627
+ };
7628
+ 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(
7629
+ YearViewMonth,
7630
+ {
7631
+ month,
7632
+ events: filteredEvents,
7633
+ onMonthClick: () => handleMonthClick(month),
7634
+ onDateClick: handleDateClick
7635
+ },
7636
+ month.toString()
7637
+ )) }) }) });
7638
+ }
7639
+ function YearViewMonth({
7640
+ month,
7641
+ events,
7642
+ onMonthClick,
7643
+ onDateClick
7644
+ }) {
7645
+ const cells = getCalendarCells(month);
7646
+ const monthEvents = events.filter((event) => {
7647
+ const eventStart = parseISO(event.startDate);
7648
+ return isSameMonth(eventStart, month);
7649
+ });
7650
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-sm border border-border/50 bg-card p-3", children: [
7651
+ /* @__PURE__ */ jsxs(
7652
+ "button",
7653
+ {
7654
+ type: "button",
7655
+ onClick: onMonthClick,
7656
+ className: "mb-2 w-full text-left text-sm font-semibold transition-colors hover:text-primary",
7657
+ children: [
7658
+ format(month, "MMMM"),
7659
+ monthEvents.length > 0 && /* @__PURE__ */ jsxs("span", { className: "ml-2 text-xs font-normal text-muted-foreground", children: [
7660
+ "(",
7661
+ monthEvents.length,
7662
+ ")"
7663
+ ] })
7664
+ ]
7665
+ }
7666
+ ),
7667
+ /* @__PURE__ */ jsx("div", { className: "mb-1 grid grid-cols-7", children: ["S", "M", "T", "W", "T", "F", "S"].map((day, i) => /* @__PURE__ */ jsx(
7668
+ "div",
7669
+ {
7670
+ className: "text-center text-[10px] font-medium text-muted-foreground",
7671
+ children: day
7672
+ },
7673
+ i
7674
+ )) }),
7675
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7", children: cells.map((cell) => /* @__PURE__ */ jsx(
7676
+ YearViewDayCell,
7677
+ {
7678
+ cell,
7679
+ month,
7680
+ events,
7681
+ onDateClick
7682
+ },
7683
+ cell.date.toISOString()
7684
+ )) })
7685
+ ] });
7686
+ }
7687
+ function YearViewDayCell({
7688
+ cell,
7689
+ month,
7690
+ events,
7691
+ onDateClick
7692
+ }) {
7693
+ const { date, currentMonth } = cell;
7694
+ const isCurrentDay = isToday(date);
7695
+ const dayEvents = events.filter((event) => {
7696
+ const eventStart = parseISO(event.startDate);
7697
+ const eventEnd = parseISO(event.endDate);
7698
+ return date >= eventStart && date <= eventEnd || isSameDay(eventStart, date) || isSameDay(eventEnd, date);
7699
+ });
7700
+ const hasEvents = dayEvents.length > 0;
7701
+ if (!currentMonth) {
7702
+ return /* @__PURE__ */ jsx("div", { className: "aspect-square" });
7703
+ }
7704
+ return /* @__PURE__ */ jsxs(
7705
+ "button",
7706
+ {
7707
+ type: "button",
7708
+ onClick: () => onDateClick(date),
7709
+ className: cn(
7710
+ "relative flex aspect-square items-center justify-center text-[11px] transition-colors",
7711
+ "hover:bg-muted rounded-sm",
7712
+ isCurrentDay && "bg-primary text-primary-foreground rounded-sm hover:bg-primary/90"
7713
+ ),
7714
+ children: [
7715
+ cell.day,
7716
+ hasEvents && !isCurrentDay && /* @__PURE__ */ jsx("span", { className: "absolute bottom-0.5 left-1/2 size-1 -translate-x-1/2 rounded-full bg-primary" })
7717
+ ]
7718
+ }
7719
+ );
7720
+ }
7721
+ var colorClasses2 = {
7722
+ blue: { border: "border-l-blue-500", bg: "bg-blue-50 dark:bg-blue-950/20" },
7723
+ green: { border: "border-l-green-500", bg: "bg-green-50 dark:bg-green-950/20" },
7724
+ red: { border: "border-l-red-500", bg: "bg-red-50 dark:bg-red-950/20" },
7725
+ yellow: { border: "border-l-yellow-500", bg: "bg-yellow-50 dark:bg-yellow-950/20" },
7726
+ purple: { border: "border-l-purple-500", bg: "bg-purple-50 dark:bg-purple-950/20" },
7727
+ orange: { border: "border-l-primary", bg: "bg-orange-50 dark:bg-orange-950/20" }
7728
+ };
7729
+ function AgendaView({
7730
+ className,
7731
+ emptyMessage = "No events scheduled for the selected month",
7732
+ onEventClick,
7733
+ onDateClick
7734
+ }) {
7735
+ const { selectedDate, setSelectedDate, setView } = useEventCalendar();
7736
+ const filteredEvents = useFilteredEvents();
7737
+ const { singleDayEvents, multiDayEvents } = React15.useMemo(
7738
+ () => splitEventsByDuration(filteredEvents),
7739
+ [filteredEvents]
7740
+ );
7741
+ const eventsByDay = React15.useMemo(() => {
7742
+ const allDates = /* @__PURE__ */ new Map();
7743
+ singleDayEvents.forEach((event) => {
7744
+ const eventDate = parseISO(event.startDate);
7745
+ if (!isSameMonth(eventDate, selectedDate)) return;
7746
+ const dateKey = format(eventDate, "yyyy-MM-dd");
7747
+ if (!allDates.has(dateKey)) {
7748
+ allDates.set(dateKey, {
7749
+ date: startOfDay(eventDate),
7750
+ events: [],
7751
+ multiDayEvents: []
7752
+ });
7753
+ }
7754
+ allDates.get(dateKey)?.events.push(event);
7755
+ });
7756
+ multiDayEvents.forEach((event) => {
7757
+ const eventStart = parseISO(event.startDate);
7758
+ const eventEnd = parseISO(event.endDate);
7759
+ let currentDate = startOfDay(eventStart);
7760
+ const lastDate = endOfDay(eventEnd);
7761
+ while (currentDate <= lastDate) {
7762
+ if (isSameMonth(currentDate, selectedDate)) {
7763
+ const dateKey = format(currentDate, "yyyy-MM-dd");
7764
+ if (!allDates.has(dateKey)) {
7765
+ allDates.set(dateKey, {
7766
+ date: new Date(currentDate),
7767
+ events: [],
7768
+ multiDayEvents: []
7769
+ });
7770
+ }
7771
+ allDates.get(dateKey)?.multiDayEvents.push(event);
7772
+ }
7773
+ currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1));
7774
+ }
7775
+ });
7776
+ return Array.from(allDates.values()).sort(
7777
+ (a, b) => a.date.getTime() - b.date.getTime()
7778
+ );
7779
+ }, [singleDayEvents, multiDayEvents, selectedDate]);
7780
+ const hasAnyEvents = singleDayEvents.length > 0 || multiDayEvents.length > 0;
7781
+ const handleDateClick = (date) => {
7782
+ setSelectedDate(date);
7783
+ setView("day");
7784
+ onDateClick?.(date);
7785
+ };
7786
+ 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: [
7787
+ eventsByDay.map((dayGroup) => /* @__PURE__ */ jsx(
7788
+ AgendaDayGroup,
7789
+ {
7790
+ date: dayGroup.date,
7791
+ events: dayGroup.events,
7792
+ multiDayEvents: dayGroup.multiDayEvents,
7793
+ onDateClick: handleDateClick,
7794
+ onEventClick
7795
+ },
7796
+ format(dayGroup.date, "yyyy-MM-dd")
7797
+ )),
7798
+ !hasAnyEvents && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center gap-2 py-20 text-muted-foreground", children: [
7799
+ /* @__PURE__ */ jsx(CalendarX2, { className: "size-10" }),
7800
+ /* @__PURE__ */ jsx("p", { className: "text-sm md:text-base", children: emptyMessage })
7801
+ ] })
7802
+ ] }) }) });
7803
+ }
7804
+ function AgendaDayGroup({
7805
+ date,
7806
+ events,
7807
+ multiDayEvents,
7808
+ onDateClick,
7809
+ onEventClick
7810
+ }) {
7811
+ const isCurrentDay = isToday(date);
7812
+ return /* @__PURE__ */ jsxs("div", { children: [
7813
+ /* @__PURE__ */ jsxs(
7814
+ "button",
7815
+ {
7816
+ type: "button",
7817
+ onClick: () => onDateClick(date),
7818
+ className: cn(
7819
+ "mb-3 flex items-center gap-2 text-left transition-colors hover:text-primary",
7820
+ isCurrentDay && "text-primary"
7821
+ ),
7822
+ children: [
7823
+ /* @__PURE__ */ jsx(
7824
+ "span",
7825
+ {
7826
+ className: cn(
7827
+ "flex size-8 items-center justify-center rounded-full text-sm font-bold",
7828
+ isCurrentDay && "bg-primary text-primary-foreground"
7829
+ ),
7830
+ children: format(date, "d")
7831
+ }
7832
+ ),
7833
+ /* @__PURE__ */ jsxs("div", { children: [
7834
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: format(date, "EEEE") }),
7835
+ /* @__PURE__ */ jsx("span", { className: "ml-2 text-muted-foreground", children: format(date, "MMMM d, yyyy") })
7836
+ ] })
7837
+ ]
7838
+ }
7839
+ ),
7840
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 pl-10", children: [
7841
+ multiDayEvents.map((event) => /* @__PURE__ */ jsx(
7842
+ AgendaEventCard,
7843
+ {
7844
+ event,
7845
+ isMultiDay: true,
7846
+ onClick: () => onEventClick?.(event)
7847
+ },
7848
+ `multi-${event.id}`
7849
+ )),
7850
+ events.map((event) => /* @__PURE__ */ jsx(
7851
+ AgendaEventCard,
7852
+ {
7853
+ event,
7854
+ onClick: () => onEventClick?.(event)
7855
+ },
7856
+ event.id
7857
+ ))
7858
+ ] })
7859
+ ] });
7860
+ }
7861
+ function AgendaEventCard({ event, isMultiDay, onClick }) {
7862
+ const colors = colorClasses2[event.color];
7863
+ const startTime = format(parseISO(event.startDate), "h:mm a");
7864
+ const endTime = format(parseISO(event.endDate), "h:mm a");
7865
+ const getInitials = (name) => {
7866
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
7867
+ };
7868
+ return /* @__PURE__ */ jsxs(
7869
+ "button",
7870
+ {
7871
+ type: "button",
7872
+ onClick,
7873
+ className: cn(
7874
+ "flex w-full items-start gap-3 rounded-lg border-l-4 p-3 text-left transition-colors",
7875
+ "hover:opacity-90",
7876
+ colors.border,
7877
+ colors.bg
7878
+ ),
7879
+ children: [
7880
+ /* @__PURE__ */ jsxs(Avatar, { className: "size-10 shrink-0", children: [
7881
+ /* @__PURE__ */ jsx(AvatarImage, { src: event.user.picturePath, alt: event.user.name }),
7882
+ /* @__PURE__ */ jsx(AvatarFallback, { children: getInitials(event.user.name) })
7883
+ ] }),
7884
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
7885
+ isMultiDay && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Multi-day event" }),
7886
+ /* @__PURE__ */ jsx("h3", { className: "font-semibold truncate", children: event.title }),
7887
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: event.user.name }),
7888
+ /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
7889
+ startTime,
7890
+ " - ",
7891
+ endTime
7892
+ ] }),
7893
+ event.description && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground line-clamp-2", children: event.description })
7894
+ ] })
7895
+ ]
7896
+ }
7897
+ );
7898
+ }
7899
+ var VIEW_CONFIG = [
7900
+ { view: "day", icon: List, label: "View by day" },
7901
+ { view: "week", icon: Columns, label: "View by week" },
7902
+ { view: "month", icon: Grid2x2, label: "View by month" },
7903
+ { view: "year", icon: Grid3x3, label: "View by year" },
7904
+ { view: "agenda", icon: CalendarRange, label: "View by agenda" }
7905
+ ];
7906
+ function CalendarHeader({
7907
+ className,
7908
+ showViewSwitcher = true,
7909
+ showUserFilter = true,
7910
+ showBadgeVariant = false,
7911
+ // Hidden by default, controlled via settings
7912
+ showToday = true,
7913
+ showAddButton = true,
7914
+ onAddClick
7915
+ }) {
7916
+ const {
7917
+ selectedDate,
7918
+ view,
7919
+ setView,
7920
+ setSelectedDate,
7921
+ selectedUserId,
7922
+ setSelectedUserId,
7923
+ users,
7924
+ badgeVariant,
7925
+ setBadgeVariant,
7926
+ goToPrevious,
7927
+ goToNext
7928
+ } = useEventCalendar();
7929
+ const filteredEvents = useFilteredEvents();
7930
+ const eventCount = filteredEvents.length;
7931
+ const { start: rangeStart, end: rangeEnd } = getViewDateRange(selectedDate, view);
7932
+ const dateRangeLabel = formatDateRange(rangeStart, rangeEnd);
7933
+ const getInitials = (name) => {
7934
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
7935
+ };
7936
+ const handleTodayClick = () => {
7937
+ setSelectedDate(/* @__PURE__ */ new Date());
7938
+ };
7939
+ const today = /* @__PURE__ */ new Date();
7940
+ return /* @__PURE__ */ jsxs(
7941
+ "div",
7942
+ {
7943
+ className: cn(
7944
+ "flex flex-col gap-4 border-b border-border p-4 lg:flex-row lg:items-center lg:justify-between",
7945
+ className
7946
+ ),
7947
+ children: [
7948
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
7949
+ /* @__PURE__ */ jsxs(
7950
+ "button",
7951
+ {
7952
+ type: "button",
7953
+ onClick: handleTodayClick,
7954
+ 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",
7955
+ children: [
7956
+ /* @__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() }),
7957
+ /* @__PURE__ */ jsx("p", { className: "flex w-full flex-1 items-center justify-center text-lg font-bold", children: today.getDate() })
7958
+ ]
7959
+ }
7960
+ ),
7961
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
7962
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7963
+ /* @__PURE__ */ jsxs("span", { className: "text-lg font-semibold", children: [
7964
+ format(selectedDate, "MMMM"),
7965
+ " ",
7966
+ selectedDate.getFullYear()
7967
+ ] }),
7968
+ /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "px-1.5", children: [
7969
+ eventCount,
7970
+ " event",
7971
+ eventCount !== 1 ? "s" : ""
7972
+ ] })
7973
+ ] }),
7974
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7975
+ /* @__PURE__ */ jsxs(
7976
+ Button,
7977
+ {
7978
+ variant: "outline",
7979
+ size: "icon",
7980
+ className: "size-7 [&_svg]:size-4",
7981
+ onClick: goToPrevious,
7982
+ children: [
7983
+ /* @__PURE__ */ jsx(ChevronLeft, {}),
7984
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Previous" })
7985
+ ]
7986
+ }
7987
+ ),
7988
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: dateRangeLabel }),
7989
+ /* @__PURE__ */ jsxs(
7990
+ Button,
7991
+ {
7992
+ variant: "outline",
7993
+ size: "icon",
7994
+ className: "size-7 [&_svg]:size-4",
7995
+ onClick: goToNext,
7996
+ children: [
7997
+ /* @__PURE__ */ jsx(ChevronRight, {}),
7998
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Next" })
7999
+ ]
8000
+ }
8001
+ )
8002
+ ] })
8003
+ ] })
8004
+ ] }),
8005
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1.5 sm:flex-row sm:justify-between", children: [
8006
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-1.5", children: [
8007
+ 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) => {
8008
+ const Icon2 = config.icon;
8009
+ const isFirst = index === 0;
8010
+ const isLast = index === VIEW_CONFIG.length - 1;
8011
+ const isActive = view === config.view;
8012
+ return /* @__PURE__ */ jsx(
8013
+ Button,
8014
+ {
8015
+ "aria-label": config.label,
8016
+ size: "icon",
8017
+ variant: isActive ? "default" : "ghost",
8018
+ className: cn(
8019
+ "size-8 border-0 [&_svg]:size-4",
8020
+ isFirst && "rounded-l-full rounded-r-sm",
8021
+ isLast && "rounded-r-full rounded-l-sm",
8022
+ !isFirst && !isLast && "rounded-sm"
8023
+ ),
8024
+ onClick: () => setView(config.view),
8025
+ children: /* @__PURE__ */ jsx(Icon2, { strokeWidth: 1.8 })
8026
+ },
8027
+ config.view
8028
+ );
8029
+ }) }),
8030
+ showUserFilter && users.length > 0 && /* @__PURE__ */ jsxs(
8031
+ Select,
8032
+ {
8033
+ value: selectedUserId || "all",
8034
+ onValueChange: (value) => setSelectedUserId(value === "all" ? null : value),
8035
+ children: [
8036
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "flex-1 md:w-48", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8037
+ /* @__PURE__ */ jsxs(SelectContent, { align: "end", children: [
8038
+ /* @__PURE__ */ jsx(SelectItem, { value: "all", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8039
+ /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
8040
+ users.slice(0, 2).map((user) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-background", children: [
8041
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.picturePath, alt: user.name }),
8042
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[10px]", children: getInitials(user.name) })
8043
+ ] }, user.id)),
8044
+ 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: [
8045
+ "+",
8046
+ users.length - 2
8047
+ ] })
8048
+ ] }),
8049
+ "All"
8050
+ ] }) }),
8051
+ users.map((user) => /* @__PURE__ */ jsx(SelectItem, { value: user.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8052
+ /* @__PURE__ */ jsxs(Avatar, { className: "size-6", children: [
8053
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.picturePath, alt: user.name }),
8054
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-[10px]", children: getInitials(user.name) })
8055
+ ] }),
8056
+ /* @__PURE__ */ jsx("p", { className: "truncate", children: user.name })
8057
+ ] }) }, user.id))
8058
+ ] })
8059
+ ]
8060
+ }
8061
+ )
8062
+ ] }),
8063
+ showAddButton && /* @__PURE__ */ jsxs(Button, { onClick: onAddClick, className: "w-full sm:w-auto", children: [
8064
+ /* @__PURE__ */ jsx(Plus, {}),
8065
+ "Add Event"
8066
+ ] })
8067
+ ] })
8068
+ ]
8069
+ }
8070
+ );
8071
+ }
8072
+ function CalendarHeaderCompact({
8073
+ className,
8074
+ showAddButton = true,
8075
+ onAddClick
8076
+ }) {
8077
+ const {
8078
+ selectedDate,
8079
+ setSelectedDate,
8080
+ view,
8081
+ setView,
8082
+ goToPrevious,
8083
+ goToNext
8084
+ } = useEventCalendar();
8085
+ const filteredEvents = useFilteredEvents();
8086
+ const eventCount = filteredEvents.length;
8087
+ const today = /* @__PURE__ */ new Date();
8088
+ const handleTodayClick = () => {
8089
+ setSelectedDate(/* @__PURE__ */ new Date());
8090
+ };
8091
+ return /* @__PURE__ */ jsxs(
8092
+ "div",
8093
+ {
8094
+ className: cn(
8095
+ "flex items-center justify-between border-b border-border p-3",
8096
+ className
8097
+ ),
8098
+ children: [
8099
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8100
+ /* @__PURE__ */ jsxs(
8101
+ "button",
8102
+ {
8103
+ type: "button",
8104
+ onClick: handleTodayClick,
8105
+ className: "flex size-10 flex-col items-start overflow-hidden rounded border focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
8106
+ children: [
8107
+ /* @__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() }),
8108
+ /* @__PURE__ */ jsx("p", { className: "flex w-full flex-1 items-center justify-center text-sm font-bold", children: today.getDate() })
8109
+ ]
8110
+ }
8111
+ ),
8112
+ /* @__PURE__ */ jsxs("div", { children: [
8113
+ /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold", children: format(selectedDate, "MMM yyyy") }),
8114
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
8115
+ eventCount,
8116
+ " events"
8117
+ ] })
8118
+ ] })
8119
+ ] }),
8120
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8121
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-8", onClick: goToPrevious, children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" }) }),
8122
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-8", onClick: goToNext, children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" }) }),
8123
+ /* @__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: [
8124
+ /* @__PURE__ */ jsx(
8125
+ Button,
8126
+ {
8127
+ size: "icon",
8128
+ variant: view === "day" ? "default" : "ghost",
8129
+ className: "size-6 rounded-l-full rounded-r-sm border-0 [&_svg]:size-3",
8130
+ onClick: () => setView("day"),
8131
+ children: /* @__PURE__ */ jsx(List, { strokeWidth: 1.8 })
8132
+ }
8133
+ ),
8134
+ /* @__PURE__ */ jsx(
8135
+ Button,
8136
+ {
8137
+ size: "icon",
8138
+ variant: view === "week" ? "default" : "ghost",
8139
+ className: "size-6 rounded-sm border-0 [&_svg]:size-3",
8140
+ onClick: () => setView("week"),
8141
+ children: /* @__PURE__ */ jsx(Columns, { strokeWidth: 1.8 })
8142
+ }
8143
+ ),
8144
+ /* @__PURE__ */ jsx(
8145
+ Button,
8146
+ {
8147
+ size: "icon",
8148
+ variant: view === "month" ? "default" : "ghost",
8149
+ className: "size-6 rounded-r-full rounded-l-sm border-0 [&_svg]:size-3",
8150
+ onClick: () => setView("month"),
8151
+ children: /* @__PURE__ */ jsx(Grid2x2, { strokeWidth: 1.8 })
8152
+ }
8153
+ )
8154
+ ] }),
8155
+ showAddButton && /* @__PURE__ */ jsx(Button, { size: "sm", onClick: onAddClick, className: "ml-2 size-8 p-0", children: /* @__PURE__ */ jsx(Plus, { className: "size-4" }) })
8156
+ ] })
8157
+ ]
8158
+ }
8159
+ );
8160
+ }
8161
+ var EVENT_COLORS2 = [
8162
+ { value: "blue", label: "Blue", className: "bg-blue-500" },
8163
+ { value: "green", label: "Green", className: "bg-green-500" },
8164
+ { value: "red", label: "Red", className: "bg-red-500" },
8165
+ { value: "yellow", label: "Yellow", className: "bg-yellow-500" },
8166
+ { value: "purple", label: "Purple", className: "bg-purple-500" },
8167
+ { value: "orange", label: "Orange", className: "bg-primary" }
8168
+ ];
8169
+ function EventDialog({
8170
+ open,
8171
+ onOpenChange,
8172
+ mode = "add",
8173
+ event,
8174
+ defaultDate = /* @__PURE__ */ new Date(),
8175
+ defaultUserId
8176
+ }) {
8177
+ const { addEvent, updateEvent, deleteEvent, users } = useEventCalendar();
8178
+ const [title, setTitle] = React15.useState("");
8179
+ const [description, setDescription] = React15.useState("");
8180
+ const [startDate, setStartDate] = React15.useState("");
8181
+ const [startTime, setStartTime] = React15.useState("");
8182
+ const [endDate, setEndDate] = React15.useState("");
8183
+ const [endTime, setEndTime] = React15.useState("");
8184
+ const [color, setColor] = React15.useState("blue");
8185
+ const [userId, setUserId] = React15.useState("");
8186
+ const [isSubmitting, setIsSubmitting] = React15.useState(false);
8187
+ React15.useEffect(() => {
8188
+ if (open) {
8189
+ if (mode === "edit" && event) {
8190
+ const start = parseISO(event.startDate);
8191
+ const end = parseISO(event.endDate);
8192
+ setTitle(event.title);
8193
+ setDescription(event.description || "");
8194
+ setStartDate(format(start, "yyyy-MM-dd"));
8195
+ setStartTime(format(start, "HH:mm"));
8196
+ setEndDate(format(end, "yyyy-MM-dd"));
8197
+ setEndTime(format(end, "HH:mm"));
8198
+ setColor(event.color);
8199
+ setUserId(event.user.id);
8200
+ } else {
8201
+ const start = defaultDate;
8202
+ const end = setMinutes(setHours(defaultDate, defaultDate.getHours() + 1), 0);
8203
+ setTitle("");
8204
+ setDescription("");
8205
+ setStartDate(format(start, "yyyy-MM-dd"));
8206
+ setStartTime(format(start, "HH:mm"));
8207
+ setEndDate(format(end, "yyyy-MM-dd"));
8208
+ setEndTime(format(end, "HH:mm"));
8209
+ setColor("blue");
8210
+ setUserId(defaultUserId || users[0]?.id || "");
8211
+ }
8212
+ }
8213
+ }, [open, mode, event, defaultDate, defaultUserId, users]);
8214
+ const handleSubmit = async (e) => {
8215
+ e.preventDefault();
8216
+ setIsSubmitting(true);
8217
+ try {
8218
+ const [startYear, startMonth, startDay] = startDate.split("-").map(Number);
8219
+ const [startHour, startMinute] = startTime.split(":").map(Number);
8220
+ const [endYear, endMonth, endDay] = endDate.split("-").map(Number);
8221
+ const [endHour, endMinute] = endTime.split(":").map(Number);
8222
+ const startDateTime = new Date(startYear, startMonth - 1, startDay, startHour, startMinute);
8223
+ const endDateTime = new Date(endYear, endMonth - 1, endDay, endHour, endMinute);
8224
+ const selectedUser = users.find((u) => u.id === userId);
8225
+ if (mode === "edit" && event) {
8226
+ const updatedEvent = {
8227
+ ...event,
8228
+ title,
8229
+ description,
8230
+ startDate: startDateTime.toISOString(),
8231
+ endDate: endDateTime.toISOString(),
8232
+ color,
8233
+ user: {
8234
+ id: userId,
8235
+ name: selectedUser?.name || "Unknown"
8236
+ }
8237
+ };
8238
+ updateEvent(updatedEvent);
8239
+ } else {
8240
+ const newEvent = {
8241
+ id: generateEventId(),
8242
+ title,
8243
+ description,
8244
+ startDate: startDateTime.toISOString(),
8245
+ endDate: endDateTime.toISOString(),
8246
+ color,
8247
+ user: {
8248
+ id: userId,
8249
+ name: selectedUser?.name || "Unknown"
8250
+ }
8251
+ };
8252
+ addEvent(newEvent);
8253
+ }
8254
+ onOpenChange(false);
8255
+ } catch (error) {
8256
+ console.error("Failed to save event:", error);
8257
+ } finally {
8258
+ setIsSubmitting(false);
8259
+ }
8260
+ };
8261
+ const handleDelete = () => {
8262
+ if (event) {
8263
+ deleteEvent(event.id);
8264
+ onOpenChange(false);
8265
+ }
8266
+ };
8267
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(DialogContent, { className: "sm:max-w-[500px]", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
8268
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
8269
+ /* @__PURE__ */ jsx(DialogTitle, { children: mode === "edit" ? "Edit Event" : "Add Event" }),
8270
+ /* @__PURE__ */ jsx(DialogDescription, { children: mode === "edit" ? "Make changes to your event below." : "Fill in the details for your new event." })
8271
+ ] }),
8272
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 py-4", children: [
8273
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8274
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "title", children: "Title" }),
8275
+ /* @__PURE__ */ jsx(
8276
+ Input,
8277
+ {
8278
+ id: "title",
8279
+ value: title,
8280
+ onChange: (e) => setTitle(e.target.value),
8281
+ placeholder: "Event title",
8282
+ required: true
8283
+ }
8284
+ )
8285
+ ] }),
8286
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8287
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "description", children: "Description" }),
8288
+ /* @__PURE__ */ jsx(
8289
+ Textarea,
8290
+ {
8291
+ id: "description",
8292
+ value: description,
8293
+ onChange: (e) => setDescription(e.target.value),
8294
+ placeholder: "Event description (optional)",
8295
+ rows: 3
8296
+ }
8297
+ )
8298
+ ] }),
8299
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8300
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8301
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "startDate", children: "Start Date" }),
8302
+ /* @__PURE__ */ jsx(
8303
+ Input,
8304
+ {
8305
+ id: "startDate",
8306
+ type: "date",
8307
+ value: startDate,
8308
+ onChange: (e) => setStartDate(e.target.value),
8309
+ required: true
8310
+ }
8311
+ )
8312
+ ] }),
8313
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8314
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "startTime", children: "Start Time" }),
8315
+ /* @__PURE__ */ jsx(
8316
+ Input,
8317
+ {
8318
+ id: "startTime",
8319
+ type: "time",
8320
+ value: startTime,
8321
+ onChange: (e) => setStartTime(e.target.value),
8322
+ required: true
8323
+ }
8324
+ )
8325
+ ] })
8326
+ ] }),
8327
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8328
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8329
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "endDate", children: "End Date" }),
8330
+ /* @__PURE__ */ jsx(
8331
+ Input,
8332
+ {
8333
+ id: "endDate",
8334
+ type: "date",
8335
+ value: endDate,
8336
+ onChange: (e) => setEndDate(e.target.value),
8337
+ required: true
8338
+ }
8339
+ )
8340
+ ] }),
8341
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8342
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "endTime", children: "End Time" }),
8343
+ /* @__PURE__ */ jsx(
8344
+ Input,
8345
+ {
8346
+ id: "endTime",
8347
+ type: "time",
8348
+ value: endTime,
8349
+ onChange: (e) => setEndTime(e.target.value),
8350
+ required: true
8351
+ }
8352
+ )
8353
+ ] })
8354
+ ] }),
8355
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8356
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8357
+ /* @__PURE__ */ jsx(Label2, { children: "Color" }),
8358
+ /* @__PURE__ */ jsxs(Select, { value: color, onValueChange: (v) => setColor(v), children: [
8359
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8360
+ /* @__PURE__ */ jsx(
8361
+ "span",
8362
+ {
8363
+ className: cn(
8364
+ "size-3 rounded-full",
8365
+ EVENT_COLORS2.find((c) => c.value === color)?.className
8366
+ )
8367
+ }
8368
+ ),
8369
+ EVENT_COLORS2.find((c) => c.value === color)?.label
8370
+ ] }) }) }),
8371
+ /* @__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: [
8372
+ /* @__PURE__ */ jsx("span", { className: cn("size-3 rounded-full", c.className) }),
8373
+ c.label
8374
+ ] }) }, c.value)) })
8375
+ ] })
8376
+ ] }),
8377
+ users.length > 0 && /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
8378
+ /* @__PURE__ */ jsx(Label2, { children: "Assignee" }),
8379
+ /* @__PURE__ */ jsxs(Select, { value: userId, onValueChange: setUserId, children: [
8380
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select user" }) }),
8381
+ /* @__PURE__ */ jsx(SelectContent, { children: users.map((user) => /* @__PURE__ */ jsx(SelectItem, { value: user.id, children: user.name }, user.id)) })
8382
+ ] })
8383
+ ] })
8384
+ ] })
8385
+ ] }),
8386
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "flex-row justify-between gap-2", children: [
8387
+ mode === "edit" ? /* @__PURE__ */ jsx(
8388
+ Button,
8389
+ {
8390
+ type: "button",
8391
+ variant: "destructive",
8392
+ onClick: handleDelete,
8393
+ disabled: isSubmitting,
8394
+ children: "Delete"
8395
+ }
8396
+ ) : /* @__PURE__ */ jsx("div", {}),
8397
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
8398
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
8399
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting || !title.trim(), children: isSubmitting ? "Saving..." : mode === "edit" ? "Save Changes" : "Add Event" })
8400
+ ] })
8401
+ ] })
8402
+ ] }) }) });
8403
+ }
8404
+ function QuickAddEvent({
8405
+ date,
8406
+ onAdd,
8407
+ onOpenDialog,
8408
+ onClose
8409
+ }) {
8410
+ const [title, setTitle] = React15.useState("");
8411
+ const { users } = useEventCalendar();
8412
+ const handleSubmit = (e) => {
8413
+ e.preventDefault();
8414
+ if (!title.trim()) return;
8415
+ const end = setMinutes(setHours(date, date.getHours() + 1), 0);
8416
+ onAdd({
8417
+ title,
8418
+ description: "",
8419
+ startDate: date.toISOString(),
8420
+ endDate: end.toISOString(),
8421
+ color: "blue",
8422
+ user: {
8423
+ id: users[0]?.id || "",
8424
+ name: users[0]?.name || "Unknown"
8425
+ }
8426
+ });
8427
+ onClose();
8428
+ };
8429
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-2 p-3", children: [
8430
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: format(date, "EEE, MMM d, h:mm a") }),
8431
+ /* @__PURE__ */ jsx(
8432
+ Input,
8433
+ {
8434
+ value: title,
8435
+ onChange: (e) => setTitle(e.target.value),
8436
+ placeholder: "Add title",
8437
+ className: "h-8",
8438
+ autoFocus: true
8439
+ }
8440
+ ),
8441
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
8442
+ /* @__PURE__ */ jsx(Button, { type: "submit", size: "sm", disabled: !title.trim(), children: "Add" }),
8443
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onOpenDialog, children: "More options" })
8444
+ ] })
8445
+ ] });
8446
+ }
8447
+ function ChangeBadgeVariantInput() {
8448
+ const { badgeVariant, setBadgeVariant } = useEventCalendar();
8449
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8450
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Change badge variant" }),
8451
+ /* @__PURE__ */ jsxs(
8452
+ Select,
8453
+ {
8454
+ value: badgeVariant,
8455
+ onValueChange: (value) => setBadgeVariant(value),
8456
+ children: [
8457
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-48", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8458
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
8459
+ /* @__PURE__ */ jsx(SelectItem, { value: "dot", children: "Dot" }),
8460
+ /* @__PURE__ */ jsx(SelectItem, { value: "colored", children: "Colored" }),
8461
+ /* @__PURE__ */ jsx(SelectItem, { value: "mixed", children: "Mixed" })
8462
+ ] })
8463
+ ]
8464
+ }
8465
+ )
8466
+ ] });
8467
+ }
8468
+ var HOUR_OPTIONS = Array.from({ length: 25 }, (_, i) => {
8469
+ if (i === 0) return { value: "0", label: "12 AM" };
8470
+ if (i === 12) return { value: "12", label: "12 PM" };
8471
+ if (i === 24) return { value: "24", label: "12 AM (next)" };
8472
+ if (i < 12) return { value: String(i), label: `${i} AM` };
8473
+ return { value: String(i), label: `${i - 12} PM` };
8474
+ });
8475
+ function ChangeVisibleHoursInput() {
8476
+ const { visibleHours, setVisibleHours } = useEventCalendar();
8477
+ const [from, setFrom] = React15.useState(visibleHours.from);
8478
+ const [to, setTo] = React15.useState(visibleHours.to);
8479
+ const handleApply = () => {
8480
+ const toHour = to === 0 ? 24 : to;
8481
+ setVisibleHours({ from, to: toHour });
8482
+ };
8483
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8484
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8485
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Change visible hours" }),
8486
+ /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 100, children: /* @__PURE__ */ jsxs(Tooltip2, { children: [
8487
+ /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(Info, { className: "size-3" }) }),
8488
+ /* @__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." }) })
8489
+ ] }) })
8490
+ ] }),
8491
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
8492
+ /* @__PURE__ */ jsx("p", { children: "From" }),
8493
+ /* @__PURE__ */ jsxs(Select, { value: String(from), onValueChange: (v) => setFrom(Number(v)), children: [
8494
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-28", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8495
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS.slice(0, 24).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8496
+ ] }),
8497
+ /* @__PURE__ */ jsx("p", { children: "To" }),
8498
+ /* @__PURE__ */ jsxs(Select, { value: String(to), onValueChange: (v) => setTo(Number(v)), children: [
8499
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-28", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8500
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS.slice(1).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8501
+ ] })
8502
+ ] }),
8503
+ /* @__PURE__ */ jsx(Button, { className: "mt-4 w-fit", onClick: handleApply, children: "Apply" })
8504
+ ] });
8505
+ }
8506
+ var DAYS_OF_WEEK = [
8507
+ { index: 0, name: "Sunday" },
8508
+ { index: 1, name: "Monday" },
8509
+ { index: 2, name: "Tuesday" },
8510
+ { index: 3, name: "Wednesday" },
8511
+ { index: 4, name: "Thursday" },
8512
+ { index: 5, name: "Friday" },
8513
+ { index: 6, name: "Saturday" }
8514
+ ];
8515
+ var HOUR_OPTIONS2 = Array.from({ length: 25 }, (_, i) => {
8516
+ if (i === 0) return { value: "0", label: "12 AM" };
8517
+ if (i === 12) return { value: "12", label: "12 PM" };
8518
+ if (i === 24) return { value: "24", label: "12 AM (next)" };
8519
+ if (i < 12) return { value: String(i), label: `${i} AM` };
8520
+ return { value: String(i), label: `${i - 12} PM` };
8521
+ });
8522
+ function ChangeWorkingHoursInput() {
8523
+ const { workingHours, setWorkingHours } = useEventCalendar();
8524
+ const [localWorkingHours, setLocalWorkingHours] = React15.useState({
8525
+ ...workingHours
8526
+ });
8527
+ const handleToggleDay = (dayId) => {
8528
+ setLocalWorkingHours((prev) => ({
8529
+ ...prev,
8530
+ [dayId]: prev[dayId].from > 0 || prev[dayId].to > 0 ? { from: 0, to: 0 } : { from: 9, to: 17 }
8531
+ }));
8532
+ };
8533
+ const handleTimeChange = (dayId, timeType, value) => {
8534
+ const hour = Number(value);
8535
+ setLocalWorkingHours((prev) => {
8536
+ const updatedDay = { ...prev[dayId], [timeType]: hour };
8537
+ if (timeType === "to" && hour === 0 && updatedDay.from === 0) {
8538
+ updatedDay.to = 24;
8539
+ }
8540
+ return { ...prev, [dayId]: updatedDay };
8541
+ });
8542
+ };
8543
+ const handleSave = () => {
8544
+ const updatedWorkingHours = { ...localWorkingHours };
8545
+ for (const dayId in updatedWorkingHours) {
8546
+ const day = updatedWorkingHours[parseInt(dayId)];
8547
+ const isDayActive = localWorkingHours[parseInt(dayId)].from > 0 || localWorkingHours[parseInt(dayId)].to > 0;
8548
+ if (isDayActive) {
8549
+ if (day.from === 0 && day.to === 0) {
8550
+ updatedWorkingHours[dayId] = { from: 0, to: 24 };
8551
+ } else if (day.to === 0 && day.from > 0) {
8552
+ updatedWorkingHours[dayId] = { ...day, to: 24 };
8553
+ }
8554
+ } else {
8555
+ updatedWorkingHours[dayId] = { from: 0, to: 0 };
8556
+ }
8557
+ }
8558
+ setWorkingHours(updatedWorkingHours);
8559
+ };
8560
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
8561
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8562
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Change working hours" }),
8563
+ /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 100, children: /* @__PURE__ */ jsxs(Tooltip2, { children: [
8564
+ /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(Info, { className: "size-3" }) }),
8565
+ /* @__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." }) })
8566
+ ] }) })
8567
+ ] }),
8568
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: DAYS_OF_WEEK.map((day) => {
8569
+ const isDayActive = localWorkingHours[day.index].from > 0 || localWorkingHours[day.index].to > 0;
8570
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-4", children: [
8571
+ /* @__PURE__ */ jsxs("div", { className: "flex w-32 items-center gap-2 sm:w-36", children: [
8572
+ /* @__PURE__ */ jsx(
8573
+ Switch,
8574
+ {
8575
+ checked: isDayActive,
8576
+ onCheckedChange: () => handleToggleDay(day.index)
8577
+ }
8578
+ ),
8579
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: day.name.slice(0, 3) })
8580
+ ] }),
8581
+ isDayActive ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
8582
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8583
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "From" }),
8584
+ /* @__PURE__ */ jsxs(
8585
+ Select,
8586
+ {
8587
+ value: String(localWorkingHours[day.index].from),
8588
+ onValueChange: (v) => handleTimeChange(day.index, "from", v),
8589
+ children: [
8590
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-24", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8591
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS2.slice(0, 24).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8592
+ ]
8593
+ }
8594
+ )
8595
+ ] }),
8596
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8597
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "To" }),
8598
+ /* @__PURE__ */ jsxs(
8599
+ Select,
8600
+ {
8601
+ value: String(localWorkingHours[day.index].to),
8602
+ onValueChange: (v) => handleTimeChange(day.index, "to", v),
8603
+ children: [
8604
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-24", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
8605
+ /* @__PURE__ */ jsx(SelectContent, { children: HOUR_OPTIONS2.slice(1).map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
8606
+ ]
8607
+ }
8608
+ )
8609
+ ] })
8610
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
8611
+ /* @__PURE__ */ jsx(Moon, { className: "size-4" }),
8612
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Closed" })
8613
+ ] })
8614
+ ] }, day.index);
8615
+ }) }),
8616
+ /* @__PURE__ */ jsx(Button, { className: "mt-4 w-fit", onClick: handleSave, children: "Apply" })
8617
+ ] });
8618
+ }
8619
+ function CalendarSettingsPanel({
8620
+ className,
8621
+ showBadgeVariant = true,
8622
+ showVisibleHours = true,
8623
+ showWorkingHours = true
8624
+ }) {
8625
+ 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: [
8626
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "flex-none gap-2 py-0 hover:no-underline", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8627
+ /* @__PURE__ */ jsx(Settings, { className: "size-4" }),
8628
+ /* @__PURE__ */ jsx("p", { className: "text-base font-semibold", children: "Calendar settings" })
8629
+ ] }) }),
8630
+ /* @__PURE__ */ jsx(AccordionContent, { children: /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col gap-6", children: [
8631
+ showBadgeVariant && /* @__PURE__ */ jsx(ChangeBadgeVariantInput, {}),
8632
+ showVisibleHours && /* @__PURE__ */ jsx(ChangeVisibleHoursInput, {}),
8633
+ showWorkingHours && /* @__PURE__ */ jsx(ChangeWorkingHoursInput, {})
8634
+ ] }) })
8635
+ ] }) });
8636
+ }
8637
+ function useMediaQuery(query) {
8638
+ const [matches, setMatches] = React15.useState(false);
8639
+ React15.useEffect(() => {
8640
+ const media = window.matchMedia(query);
8641
+ setMatches(media.matches);
8642
+ const listener = (event) => {
8643
+ setMatches(event.matches);
8644
+ };
8645
+ media.addEventListener("change", listener);
8646
+ return () => media.removeEventListener("change", listener);
8647
+ }, [query]);
8648
+ return matches;
8649
+ }
8650
+ function BigCalendar({
8651
+ className,
8652
+ compact = "auto",
8653
+ bordered = true,
8654
+ showHeader = true,
8655
+ showAddButton = true,
8656
+ showSettings = true,
8657
+ enableDragDrop = true,
8658
+ weekStartsOn = 0,
8659
+ maxEventsPerDay = 3,
8660
+ config,
8661
+ ...providerProps
8662
+ }) {
8663
+ return /* @__PURE__ */ jsx(EventCalendarProvider, { ...providerProps, children: /* @__PURE__ */ jsx(DragProvider, { children: /* @__PURE__ */ jsx(
8664
+ BigCalendarInner,
8665
+ {
8666
+ className,
8667
+ compact,
8668
+ bordered,
8669
+ showHeader,
8670
+ showAddButton,
8671
+ showSettings,
8672
+ enableDragDrop,
8673
+ weekStartsOn,
8674
+ maxEventsPerDay,
8675
+ config
8676
+ }
8677
+ ) }) });
8678
+ }
8679
+ function BigCalendarInner({
8680
+ className,
8681
+ compact,
8682
+ bordered,
8683
+ showHeader,
8684
+ showAddButton,
8685
+ showSettings,
8686
+ enableDragDrop,
8687
+ weekStartsOn,
8688
+ maxEventsPerDay
8689
+ }) {
8690
+ const { view, setView } = useEventCalendar();
8691
+ const [dialogOpen, setDialogOpen] = React15.useState(false);
8692
+ const [selectedEvent, setSelectedEvent] = React15.useState(null);
8693
+ const [dialogMode, setDialogMode] = React15.useState("add");
8694
+ const [defaultDate, setDefaultDate] = React15.useState(/* @__PURE__ */ new Date());
8695
+ const isMobile = useMediaQuery("(max-width: 768px)");
8696
+ const isCompact = compact === "auto" ? isMobile : compact;
8697
+ const handleAddClick = () => {
8698
+ setSelectedEvent(null);
8699
+ setDialogMode("add");
8700
+ setDefaultDate(/* @__PURE__ */ new Date());
8701
+ setDialogOpen(true);
8702
+ };
8703
+ const handleEventClick = (event) => {
8704
+ setSelectedEvent(event);
8705
+ setDialogMode("edit");
8706
+ setDialogOpen(true);
8707
+ };
8708
+ const handleDateClick = (date) => {
8709
+ setDefaultDate(date);
8710
+ };
8711
+ const handleMoreClick = (date, events) => {
8712
+ setDefaultDate(date);
8713
+ setView("day");
8714
+ };
8715
+ const handleTimeClick = (date, hour, minute) => {
8716
+ setSelectedEvent(null);
8717
+ setDialogMode("add");
8718
+ const clickedDate = new Date(date);
8719
+ clickedDate.setHours(hour, minute, 0, 0);
8720
+ setDefaultDate(clickedDate);
8721
+ setDialogOpen(true);
8722
+ };
8723
+ const Wrapper = bordered ? Card : "div";
8724
+ const Content14 = bordered ? CardContent : "div";
8725
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
8726
+ /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4 relative", className), children: [
8727
+ /* @__PURE__ */ jsxs(
8728
+ Wrapper,
8729
+ {
8730
+ className: cn(
8731
+ "flex min-h-[600px] flex-col overflow-hidden rounded-sm",
8732
+ !bordered && "border border-border bg-card"
8733
+ ),
8734
+ children: [
8735
+ showHeader && (isCompact ? /* @__PURE__ */ jsx(
8736
+ CalendarHeaderCompact,
8737
+ {
8738
+ showAddButton,
8739
+ onAddClick: handleAddClick
8740
+ }
8741
+ ) : /* @__PURE__ */ jsx(
8742
+ CalendarHeader,
8743
+ {
8744
+ showAddButton,
8745
+ onAddClick: handleAddClick
8746
+ }
8747
+ )),
8748
+ /* @__PURE__ */ jsx(Content14, { className: cn("flex-1 overflow-hidden", bordered ? "p-0" : ""), children: /* @__PURE__ */ jsx(
8749
+ CalendarView,
8750
+ {
8751
+ view,
8752
+ weekStartsOn,
8753
+ maxEventsPerDay,
8754
+ onEventClick: handleEventClick,
8755
+ onDateClick: handleDateClick,
8756
+ onMoreClick: handleMoreClick,
8757
+ onTimeClick: handleTimeClick
8758
+ }
8759
+ ) })
8760
+ ]
8761
+ }
8762
+ ),
8763
+ showSettings && /* @__PURE__ */ jsx(CalendarSettingsPanel, {})
8764
+ ] }),
8765
+ /* @__PURE__ */ jsx(
8766
+ EventDialog,
8767
+ {
8768
+ open: dialogOpen,
8769
+ onOpenChange: setDialogOpen,
8770
+ mode: dialogMode,
8771
+ event: selectedEvent,
8772
+ defaultDate
8773
+ }
8774
+ )
8775
+ ] });
8776
+ }
8777
+ function CalendarView({
8778
+ view,
8779
+ weekStartsOn,
8780
+ maxEventsPerDay,
8781
+ onEventClick,
8782
+ onDateClick,
8783
+ onMoreClick,
8784
+ onTimeClick
8785
+ }) {
8786
+ switch (view) {
8787
+ case "month":
8788
+ return /* @__PURE__ */ jsx(
8789
+ MonthView,
8790
+ {
8791
+ className: "h-full",
8792
+ weekStartsOn,
8793
+ maxEventsPerDay,
8794
+ onEventClick,
8795
+ onDateClick,
8796
+ onMoreClick
8797
+ }
8798
+ );
8799
+ case "week":
8800
+ return /* @__PURE__ */ jsx(
8801
+ WeekView,
8802
+ {
8803
+ className: "h-full",
8804
+ weekStartsOn,
8805
+ onEventClick,
8806
+ onDateClick,
8807
+ onTimeClick
8808
+ }
8809
+ );
8810
+ case "day":
8811
+ return /* @__PURE__ */ jsx(
8812
+ DayView,
8813
+ {
8814
+ className: "h-full",
8815
+ onEventClick,
8816
+ onTimeClick
8817
+ }
8818
+ );
8819
+ case "year":
8820
+ return /* @__PURE__ */ jsx(
8821
+ YearView,
8822
+ {
8823
+ className: "h-full",
8824
+ weekStartsOn,
8825
+ onDateClick
8826
+ }
8827
+ );
8828
+ case "agenda":
8829
+ return /* @__PURE__ */ jsx(
8830
+ AgendaView,
8831
+ {
8832
+ className: "h-full",
8833
+ onEventClick,
8834
+ onDateClick
8835
+ }
8836
+ );
8837
+ default:
8838
+ return null;
8839
+ }
8840
+ }
5430
8841
 
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 };
8842
+ 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, ThemeSwitch, 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
8843
  //# sourceMappingURL=index.js.map
5433
8844
  //# sourceMappingURL=index.js.map