@addsign/moje-agenda-shared-lib 1.0.60 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/Dialog-DZMfjbGC.js +421 -0
  2. package/dist/Dialog-DZMfjbGC.js.map +1 -0
  3. package/dist/assets/style.css +4369 -0
  4. package/dist/assets/tailwind.css +1365 -1193
  5. package/dist/check-B7dJm08z.js +12 -0
  6. package/dist/check-B7dJm08z.js.map +1 -0
  7. package/dist/components/Button.js +1 -1
  8. package/dist/components/datatable/DataTable.js +6 -2
  9. package/dist/components/datatable/DataTable.js.map +1 -1
  10. package/dist/components/datatable/DataTableServer.js +6 -2
  11. package/dist/components/datatable/DataTableServer.js.map +1 -1
  12. package/dist/components/form/AutocompleteSearchBar.js +6 -2
  13. package/dist/components/form/AutocompleteSearchBar.js.map +1 -1
  14. package/dist/components/form/AutocompleteSearchBarServer.js +6 -2
  15. package/dist/components/form/AutocompleteSearchBarServer.js.map +1 -1
  16. package/dist/components/form/FileInput.js +7 -3
  17. package/dist/components/form/FileInput.js.map +1 -1
  18. package/dist/components/form/FileInputMultiple.js +7 -3
  19. package/dist/components/form/FileInputMultiple.js.map +1 -1
  20. package/dist/components/form/FormField.js +6 -2
  21. package/dist/components/form/FormField.js.map +1 -1
  22. package/dist/components/form/PositionsSelectorSingle.js +6 -2
  23. package/dist/components/form/PositionsSelectorSingle.js.map +1 -1
  24. package/dist/components/form/SelectField.js +6 -2
  25. package/dist/components/form/SelectField.js.map +1 -1
  26. package/dist/components/profiles/ProfileOverview.js +6 -2
  27. package/dist/components/profiles/ProfileOverview.js.map +1 -1
  28. package/dist/components/ui/Combobox.d.ts +1 -0
  29. package/dist/components/ui/Combobox.js +138 -0
  30. package/dist/components/ui/Combobox.js.map +1 -0
  31. package/dist/components/ui/DateTimePicker.js +19 -5
  32. package/dist/components/ui/DateTimePicker.js.map +1 -1
  33. package/dist/components/ui/Dialog.js +15 -413
  34. package/dist/components/ui/Dialog.js.map +1 -1
  35. package/dist/components/ui/ScrollArea.js +2 -1
  36. package/dist/components/ui/ScrollArea.js.map +1 -1
  37. package/dist/components/ui/command.d.ts +80 -0
  38. package/dist/components/ui/command.js +643 -0
  39. package/dist/components/ui/command.js.map +1 -0
  40. package/dist/components/ui/datepicker.js +14 -1
  41. package/dist/components/ui/datepicker.js.map +1 -1
  42. package/dist/components/ui/popover.js +3 -2
  43. package/dist/components/ui/popover.js.map +1 -1
  44. package/dist/components/ui/radioGroup.d.ts +5 -0
  45. package/dist/components/ui/radioGroup.js +586 -0
  46. package/dist/components/ui/radioGroup.js.map +1 -0
  47. package/dist/components/ui/select.js +9 -144
  48. package/dist/components/ui/select.js.map +1 -1
  49. package/dist/index-BXrwe-_7.js +1395 -0
  50. package/dist/index-BXrwe-_7.js.map +1 -0
  51. package/dist/index-Bk8dRTPE.js +11 -0
  52. package/dist/index-Bk8dRTPE.js.map +1 -0
  53. package/dist/index-BlzC-wss.js +140 -0
  54. package/dist/index-BlzC-wss.js.map +1 -0
  55. package/dist/index-Bp9GiUkg.js +2266 -0
  56. package/dist/index-Bp9GiUkg.js.map +1 -0
  57. package/dist/index-BzVVosDl.js +57 -0
  58. package/dist/index-BzVVosDl.js.map +1 -0
  59. package/dist/index-CbAQSs_C.js +40 -0
  60. package/dist/index-CbAQSs_C.js.map +1 -0
  61. package/dist/index-Dz_fWpFA.js +2203 -0
  62. package/dist/index-Dz_fWpFA.js.map +1 -0
  63. package/dist/index-IXOTxK3N.js +7 -0
  64. package/dist/index-IXOTxK3N.js.map +1 -0
  65. package/dist/main.d.ts +3 -0
  66. package/dist/main.js +29 -12
  67. package/dist/main.js.map +1 -1
  68. package/dist/parse-D2yb8751.js +1727 -0
  69. package/dist/parse-D2yb8751.js.map +1 -0
  70. package/dist/tailwind-l0sNRNKZ.js +2 -0
  71. package/dist/tailwind-l0sNRNKZ.js.map +1 -0
  72. package/lib/components/Button.tsx +57 -0
  73. package/lib/components/Calendar.tsx +242 -0
  74. package/lib/components/ConfirmationModalDialog.tsx +115 -0
  75. package/lib/components/Modal.tsx +73 -0
  76. package/lib/components/ModalDialog.tsx +63 -0
  77. package/lib/components/Spinner.tsx +25 -0
  78. package/lib/components/SpinnerIcon.tsx +12 -0
  79. package/lib/components/datatable/DataTable.tsx +442 -0
  80. package/lib/components/datatable/DataTableServer.tsx +939 -0
  81. package/lib/components/datatable/DatatableSettings.tsx +48 -0
  82. package/lib/components/datatable/Resizable.tsx +99 -0
  83. package/lib/components/datatable/types.ts +33 -0
  84. package/lib/components/form/AutocompleteSearchBar.tsx +424 -0
  85. package/lib/components/form/AutocompleteSearchBarServer.tsx +257 -0
  86. package/lib/components/form/DateField.tsx +124 -0
  87. package/lib/components/form/DateRangeField.tsx +116 -0
  88. package/lib/components/form/FileInput.tsx +188 -0
  89. package/lib/components/form/FileInputMultiple.tsx +186 -0
  90. package/lib/components/form/FormField.tsx +371 -0
  91. package/lib/components/form/InputField.tsx +230 -0
  92. package/lib/components/form/PositionsSelectorSingle.tsx +266 -0
  93. package/lib/components/form/RadioGroup.tsx +64 -0
  94. package/lib/components/form/SelectField.tsx +267 -0
  95. package/lib/components/layout/IconInCircle.tsx +29 -0
  96. package/lib/components/layout/PageTitle.tsx +19 -0
  97. package/lib/components/layout/SectionTitle.tsx +22 -0
  98. package/lib/components/profiles/ProfileOverview.tsx +212 -0
  99. package/lib/components/ui/Calendar.tsx +68 -0
  100. package/lib/components/ui/Combobox.tsx +122 -0
  101. package/lib/components/ui/DatePicker.tsx +124 -0
  102. package/lib/components/ui/DateTimePicker.tsx +187 -0
  103. package/lib/components/ui/Dialog.tsx +118 -0
  104. package/lib/components/ui/ScrollArea.tsx +45 -0
  105. package/lib/components/ui/button.tsx +56 -0
  106. package/lib/components/ui/command.tsx +153 -0
  107. package/lib/components/ui/form.tsx +177 -0
  108. package/lib/components/ui/input.tsx +22 -0
  109. package/lib/components/ui/label.tsx +24 -0
  110. package/lib/components/ui/popover.tsx +31 -0
  111. package/lib/components/ui/radioGroup.tsx +44 -0
  112. package/lib/components/ui/select.tsx +158 -0
  113. package/lib/contexts/FederationContext.tsx +28 -0
  114. package/lib/contexts/useFederationContext.ts +4 -0
  115. package/lib/css/tailwind.css +10 -0
  116. package/lib/fonts/arial.ts +3 -0
  117. package/lib/fonts/arialBold.ts +4 -0
  118. package/lib/main.ts +64 -0
  119. package/lib/types.ts +492 -0
  120. package/lib/utils/PdfManager.ts +224 -0
  121. package/lib/utils/getFullName.tsx +83 -0
  122. package/lib/utils/getIntersectingDays.ts +28 -0
  123. package/lib/utils/handleErrors.ts +28 -0
  124. package/lib/utils/hasRightInModule.ts +17 -0
  125. package/lib/utils/hasRole.ts +12 -0
  126. package/lib/utils/utils.ts +6 -0
  127. package/lib/vite-env.d.ts +1 -0
  128. package/package.json +5 -2
@@ -0,0 +1,122 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Check, ChevronsUpDown, Plus } from "lucide-react";
5
+
6
+ import { cn } from "../../utils/utils";
7
+ import { Button } from "./button";
8
+ import {
9
+ Command,
10
+ CommandEmpty,
11
+ CommandGroup,
12
+ CommandInput,
13
+ CommandItem,
14
+ CommandList,
15
+ } from "./command";
16
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover";
17
+
18
+ const predefinedFrameworks = [
19
+ {
20
+ value: "next.js",
21
+ label: "Next.js",
22
+ },
23
+ {
24
+ value: "sveltekit",
25
+ label: "SvelteKit",
26
+ },
27
+ {
28
+ value: "nuxt.js",
29
+ label: "Nuxt.js",
30
+ },
31
+ {
32
+ value: "remix",
33
+ label: "Remix",
34
+ },
35
+ {
36
+ value: "astro",
37
+ label: "Astro",
38
+ },
39
+ ];
40
+
41
+ export default function ComboboxDemo() {
42
+ const [open, setOpen] = React.useState(false);
43
+ const [value, setValue] = React.useState("");
44
+ const [inputValue, setInputValue] = React.useState("");
45
+ const [frameworks, setFrameworks] = React.useState(predefinedFrameworks);
46
+
47
+ const handleSelect = (currentValue: string) => {
48
+ if (currentValue === "add-custom") {
49
+ if (
50
+ inputValue &&
51
+ !frameworks.some((f) => f.value === inputValue.toLowerCase())
52
+ ) {
53
+ const newFramework = {
54
+ value: inputValue.toLowerCase(),
55
+ label: inputValue,
56
+ };
57
+ setFrameworks([...frameworks, newFramework]);
58
+ setValue(newFramework.value);
59
+ }
60
+ } else {
61
+ setValue(currentValue === value ? "" : currentValue);
62
+ }
63
+ setOpen(false);
64
+ };
65
+
66
+ return (
67
+ <Popover open={open} onOpenChange={setOpen}>
68
+ <PopoverTrigger asChild>
69
+ <Button
70
+ variant="outline"
71
+ role="combobox"
72
+ aria-expanded={open}
73
+ className="w-[200px] justify-between"
74
+ >
75
+ {value
76
+ ? frameworks.find((framework) => framework.value === value)?.label
77
+ : "Select framework..."}
78
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
79
+ </Button>
80
+ </PopoverTrigger>
81
+ <PopoverContent className="w-[200px] p-0">
82
+ <Command>
83
+ <CommandInput
84
+ placeholder="Search framework..."
85
+ className="h-9"
86
+ value={inputValue}
87
+ onValueChange={setInputValue}
88
+ />
89
+ <CommandList>
90
+ <CommandEmpty>
91
+ <Button
92
+ variant="ghost"
93
+ className="w-full justify-start"
94
+ onClick={() => handleSelect("add-custom")}
95
+ >
96
+ <Plus className="mr-2 h-4 w-4" />
97
+ Add "{inputValue}"
98
+ </Button>
99
+ </CommandEmpty>
100
+ <CommandGroup>
101
+ {frameworks.map((framework) => (
102
+ <CommandItem
103
+ key={framework.value}
104
+ value={framework.value}
105
+ onSelect={handleSelect}
106
+ >
107
+ {framework.label}
108
+ <Check
109
+ className={cn(
110
+ "ml-auto h-4 w-4",
111
+ value === framework.value ? "opacity-100" : "opacity-0"
112
+ )}
113
+ />
114
+ </CommandItem>
115
+ ))}
116
+ </CommandGroup>
117
+ </CommandList>
118
+ </Command>
119
+ </PopoverContent>
120
+ </Popover>
121
+ );
122
+ }
@@ -0,0 +1,124 @@
1
+ import { format, isValid, parse } from "date-fns";
2
+ import { CalendarIcon, XIcon } from "lucide-react";
3
+
4
+ import { Button } from "./button";
5
+ import { Calendar } from "./Calendar";
6
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover";
7
+ import { cn } from "../../utils/utils";
8
+ import React, { forwardRef, useEffect } from "react";
9
+ import { Input } from "./input";
10
+
11
+ const DATE_FORMAT = "dd.MM.yyyy";
12
+
13
+ interface DatePickerProps {
14
+ value?: Date;
15
+ onChange?: (date: Date | undefined) => void;
16
+ className?: string;
17
+ placeholder?: string;
18
+ clearable?: boolean;
19
+ }
20
+
21
+ const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(
22
+ (
23
+ { value, onChange, className, clearable = true, placeholder, ...props },
24
+ ref
25
+ ) => {
26
+ const [date, setDate] = React.useState<Date | undefined>(value);
27
+ const [inputValue, setInputValue] = React.useState<string>("");
28
+
29
+ useEffect(() => {
30
+ if (value) {
31
+ setDate(value);
32
+ setInputValue(format(value, DATE_FORMAT));
33
+ } else {
34
+ setDate(undefined);
35
+ setInputValue("");
36
+ }
37
+ }, [value]);
38
+
39
+ const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
40
+ setInputValue(event.target.value);
41
+ };
42
+
43
+ const handleInputBlur = () => {
44
+ if (inputValue === "") {
45
+ setDate(undefined);
46
+ onChange?.(undefined);
47
+ return;
48
+ }
49
+
50
+ const parsedDate = parse(inputValue, DATE_FORMAT, new Date());
51
+ if (isValid(parsedDate)) {
52
+ setDate(parsedDate);
53
+ onChange?.(parsedDate);
54
+ setInputValue(format(parsedDate, DATE_FORMAT));
55
+ } else {
56
+ setInputValue("");
57
+ setDate(undefined);
58
+ onChange?.(undefined);
59
+ }
60
+ };
61
+
62
+ const handleCalendarSelect = (selectedDate: Date | undefined) => {
63
+ setDate(selectedDate);
64
+ onChange?.(selectedDate);
65
+ if (selectedDate) {
66
+ setInputValue(format(selectedDate, DATE_FORMAT));
67
+ } else {
68
+ setInputValue("");
69
+ }
70
+ };
71
+
72
+ const handleClear = () => {
73
+ setInputValue("");
74
+ setDate(undefined);
75
+ onChange?.(undefined);
76
+ };
77
+
78
+ return (
79
+ <Popover>
80
+ <PopoverTrigger asChild>
81
+ <div className={cn("relative w-full", className)}>
82
+ <Input
83
+ type="text"
84
+ value={inputValue}
85
+ onChange={handleInputChange}
86
+ onBlur={handleInputBlur}
87
+ placeholder={placeholder}
88
+ className={cn(
89
+ "w-full pl-8 pr-8",
90
+ !date && "text-muted-foreground"
91
+ )}
92
+ ref={ref}
93
+ {...props}
94
+ />
95
+ <CalendarIcon className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
96
+ {clearable && inputValue && (
97
+ <Button
98
+ variant="ghost"
99
+ size="icon"
100
+ className="absolute right-2 top-1/2 -translate-y-1/2 h-4 w-4 p-0"
101
+ onClick={handleClear}
102
+ >
103
+ <XIcon className="h-4 w-4 text-muted-foreground" />
104
+ <span className="sr-only">Smazat datum</span>
105
+ </Button>
106
+ )}
107
+ </div>
108
+ </PopoverTrigger>
109
+ <PopoverContent className="w-auto p-0" align="start">
110
+ <Calendar
111
+ mode="single"
112
+ selected={date}
113
+ onSelect={handleCalendarSelect}
114
+ initialFocus
115
+ />
116
+ </PopoverContent>
117
+ </Popover>
118
+ );
119
+ }
120
+ );
121
+
122
+ DatePicker.displayName = "DatePicker";
123
+
124
+ export default DatePicker;
@@ -0,0 +1,187 @@
1
+ import { format, parse, isValid, set } from "date-fns";
2
+ import { CalendarClockIcon, Clock, XIcon } from "lucide-react";
3
+
4
+ import { Button } from "./button";
5
+ import { Calendar } from "./Calendar";
6
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover";
7
+ import { cn } from "../../utils/utils";
8
+ import React, { forwardRef, useEffect } from "react";
9
+ import { Input } from "./input";
10
+ import {
11
+ Select,
12
+ SelectContent,
13
+ SelectItem,
14
+ SelectTrigger,
15
+ SelectValue,
16
+ } from "./select";
17
+
18
+ const DATE_FORMAT = "dd.MM.yyyy HH:mm";
19
+
20
+ interface DateTimePickerProps {
21
+ value?: Date;
22
+ onChange?: (date: Date | undefined) => void;
23
+ className?: string;
24
+ placeholder?: string;
25
+ clearable?: boolean;
26
+ }
27
+
28
+ const DateTimePicker = forwardRef<HTMLInputElement, DateTimePickerProps>(
29
+ (
30
+ { value, onChange, className, clearable = true, placeholder, ...props },
31
+ ref
32
+ ) => {
33
+ const [dateTime, setDateTime] = React.useState<Date | undefined>(value);
34
+ const [inputValue, setInputValue] = React.useState<string>("");
35
+
36
+ useEffect(() => {
37
+ if (value) {
38
+ setDateTime(value);
39
+ setInputValue(format(value, DATE_FORMAT));
40
+ } else {
41
+ setDateTime(undefined);
42
+ setInputValue("");
43
+ }
44
+ }, [value]);
45
+
46
+ const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
47
+ setInputValue(event.target.value);
48
+ };
49
+
50
+ const handleInputBlur = () => {
51
+ if (inputValue === "") {
52
+ setDateTime(undefined);
53
+ onChange?.(undefined);
54
+ return;
55
+ }
56
+
57
+ const parsedDateTime = parse(inputValue, DATE_FORMAT, new Date());
58
+ if (isValid(parsedDateTime)) {
59
+ setDateTime(parsedDateTime);
60
+ onChange?.(parsedDateTime);
61
+ setInputValue(format(parsedDateTime, DATE_FORMAT));
62
+ } else {
63
+ setInputValue("");
64
+ setDateTime(undefined);
65
+ onChange?.(undefined);
66
+ }
67
+ };
68
+
69
+ const handleDateSelect = (selectedDate: Date | undefined) => {
70
+ if (selectedDate) {
71
+ const newDateTime = dateTime
72
+ ? set(dateTime, {
73
+ year: selectedDate.getFullYear(),
74
+ month: selectedDate.getMonth(),
75
+ date: selectedDate.getDate(),
76
+ })
77
+ : set(selectedDate, { hours: 12, minutes: 0 });
78
+ setDateTime(newDateTime);
79
+ onChange?.(newDateTime);
80
+ setInputValue(format(newDateTime, DATE_FORMAT));
81
+ } else {
82
+ setDateTime(undefined);
83
+ setInputValue("");
84
+ onChange?.(undefined);
85
+ }
86
+ };
87
+
88
+ const handleTimeSelect = (time: string) => {
89
+ const [hours, minutes] = time.split(":").map(Number);
90
+ if (dateTime) {
91
+ const newDateTime = set(dateTime, { hours, minutes });
92
+ setDateTime(newDateTime);
93
+ onChange?.(newDateTime);
94
+ setInputValue(format(newDateTime, DATE_FORMAT));
95
+ } else {
96
+ const newDateTime = set(new Date(), { hours, minutes });
97
+ setDateTime(newDateTime);
98
+ onChange?.(newDateTime);
99
+ setInputValue(format(newDateTime, DATE_FORMAT));
100
+ }
101
+ };
102
+
103
+ const handleClear = () => {
104
+ setInputValue("");
105
+ setDateTime(undefined);
106
+ onChange?.(undefined);
107
+ };
108
+
109
+ const timeOptions = Array.from({ length: 48 }, (_, i) => {
110
+ const hours = Math.floor(i / 2);
111
+ const minutes = i % 2 === 0 ? "00" : "30";
112
+ return `${hours.toString().padStart(2, "0")}:${minutes}`;
113
+ });
114
+
115
+ return (
116
+ <Popover>
117
+ <PopoverTrigger asChild>
118
+ <div className={cn("relative w-full", className)}>
119
+ <Input
120
+ ref={ref}
121
+ type="text"
122
+ value={inputValue}
123
+ onChange={handleInputChange}
124
+ onBlur={handleInputBlur}
125
+ placeholder={placeholder}
126
+ className={cn(
127
+ "w-full pl-8 pr-8",
128
+ !dateTime && "text-muted-foreground"
129
+ )}
130
+ {...props}
131
+ />
132
+ <CalendarClockIcon className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
133
+ {clearable && inputValue && (
134
+ <Button
135
+ variant="ghost"
136
+ size="icon"
137
+ className="absolute right-2 top-1/2 -translate-y-1/2 h-4 w-4 p-0"
138
+ onClick={handleClear}
139
+ >
140
+ <XIcon className="h-4 w-4 text-muted-foreground" />
141
+ <span className="sr-only">Smazat datum a čas</span>
142
+ </Button>
143
+ )}
144
+ </div>
145
+ </PopoverTrigger>
146
+ <PopoverContent className="w-auto p-0" align="start">
147
+ <Calendar
148
+ mode="single"
149
+ selected={dateTime}
150
+ onSelect={handleDateSelect}
151
+ initialFocus
152
+ />
153
+ <div className="p-3 border-t border-border">
154
+ <Select
155
+ onValueChange={handleTimeSelect}
156
+ value={dateTime ? format(dateTime, "HH:mm") : undefined}
157
+ >
158
+ <SelectTrigger>
159
+ <SelectValue placeholder="Select time">
160
+ {dateTime ? (
161
+ <div className="flex items-center">
162
+ <Clock className="mr-2 h-4 w-4" />
163
+ {format(dateTime, "HH:mm")}
164
+ </div>
165
+ ) : (
166
+ "Select time"
167
+ )}
168
+ </SelectValue>
169
+ </SelectTrigger>
170
+ <SelectContent>
171
+ {timeOptions.map((time) => (
172
+ <SelectItem key={time} value={time}>
173
+ {time}
174
+ </SelectItem>
175
+ ))}
176
+ </SelectContent>
177
+ </Select>
178
+ </div>
179
+ </PopoverContent>
180
+ </Popover>
181
+ );
182
+ }
183
+ );
184
+
185
+ DateTimePicker.displayName = "DateTimePicker";
186
+
187
+ export default DateTimePicker;
@@ -0,0 +1,118 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
5
+ import { X } from "lucide-react";
6
+ import { cn } from "../../utils/utils";
7
+
8
+ const Dialog = DialogPrimitive.Root;
9
+
10
+ const DialogTrigger = DialogPrimitive.Trigger;
11
+
12
+ const DialogPortal = DialogPrimitive.Portal;
13
+
14
+ const DialogClose = DialogPrimitive.Close;
15
+
16
+ const DialogOverlay = React.forwardRef<
17
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
18
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
19
+ >(({ className, ...props }, ref) => (
20
+ <DialogPrimitive.Overlay
21
+ ref={ref}
22
+ className={cn(
23
+ "fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ ));
29
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
30
+
31
+ const DialogContent = React.forwardRef<
32
+ React.ElementRef<typeof DialogPrimitive.Content>,
33
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
34
+ >(({ className, children, ...props }, ref) => (
35
+ <DialogPortal>
36
+ <DialogOverlay />
37
+ <DialogPrimitive.Content
38
+ ref={ref}
39
+ className={cn(
40
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-white p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
41
+ className
42
+ )}
43
+ {...props}
44
+ >
45
+ {children}
46
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
47
+ <X className="h-4 w-4" />
48
+ <span className="sr-only">Close</span>
49
+ </DialogPrimitive.Close>
50
+ </DialogPrimitive.Content>
51
+ </DialogPortal>
52
+ ));
53
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
54
+
55
+ const DialogHeader = ({
56
+ className,
57
+ ...props
58
+ }: React.HTMLAttributes<HTMLDivElement>) => (
59
+ <div
60
+ className={cn("flex flex-col space-y-1.5 sm:text-left", className)}
61
+ {...props}
62
+ />
63
+ );
64
+ DialogHeader.displayName = "DialogHeader";
65
+
66
+ const DialogFooter = ({
67
+ className,
68
+ ...props
69
+ }: React.HTMLAttributes<HTMLDivElement>) => (
70
+ <div
71
+ className={cn(
72
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
73
+ className
74
+ )}
75
+ {...props}
76
+ />
77
+ );
78
+ DialogFooter.displayName = "DialogFooter";
79
+
80
+ const DialogTitle = React.forwardRef<
81
+ React.ElementRef<typeof DialogPrimitive.Title>,
82
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
83
+ >(({ className, ...props }, ref) => (
84
+ <DialogPrimitive.Title
85
+ ref={ref}
86
+ className={cn(
87
+ "text-lg font-semibold leading-none tracking-tight",
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ ));
93
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
94
+
95
+ const DialogDescription = React.forwardRef<
96
+ React.ElementRef<typeof DialogPrimitive.Description>,
97
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
98
+ >(({ className, ...props }, ref) => (
99
+ <DialogPrimitive.Description
100
+ ref={ref}
101
+ className={cn("text-sm text-muted-foreground", className)}
102
+ {...props}
103
+ />
104
+ ));
105
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
106
+
107
+ export {
108
+ Dialog,
109
+ DialogPortal,
110
+ DialogOverlay,
111
+ DialogClose,
112
+ DialogTrigger,
113
+ DialogContent,
114
+ DialogHeader,
115
+ DialogFooter,
116
+ DialogTitle,
117
+ DialogDescription,
118
+ };
@@ -0,0 +1,45 @@
1
+ import * as React from "react";
2
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3
+ import { cn } from "../../utils/utils";
4
+
5
+ const ScrollArea = React.forwardRef<
6
+ React.ElementRef<typeof ScrollAreaPrimitive.Root>,
7
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
8
+ >(({ className, children, ...props }, ref) => (
9
+ <ScrollAreaPrimitive.Root
10
+ ref={ref}
11
+ className={cn("relative overflow-hidden", className)}
12
+ {...props}
13
+ >
14
+ <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
15
+ {children}
16
+ </ScrollAreaPrimitive.Viewport>
17
+ <ScrollBar />
18
+ <ScrollAreaPrimitive.Corner />
19
+ </ScrollAreaPrimitive.Root>
20
+ ));
21
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
22
+
23
+ const ScrollBar = React.forwardRef<
24
+ React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
25
+ React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
26
+ >(({ className, orientation = "vertical", ...props }, ref) => (
27
+ <ScrollAreaPrimitive.ScrollAreaScrollbar
28
+ ref={ref}
29
+ orientation={orientation}
30
+ className={cn(
31
+ "flex touch-none select-none transition-colors",
32
+ orientation === "vertical" &&
33
+ "h-full w-2.5 border-l border-l-transparent p-[1px]",
34
+ orientation === "horizontal" &&
35
+ "h-2.5 flex-col border-t border-t-transparent p-[1px]",
36
+ className
37
+ )}
38
+ {...props}
39
+ >
40
+ <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
41
+ </ScrollAreaPrimitive.ScrollAreaScrollbar>
42
+ ));
43
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
44
+
45
+ export { ScrollArea, ScrollBar };
@@ -0,0 +1,56 @@
1
+ import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+
5
+ import { cn } from "../../utils/utils";
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-text hover:bg-primary/90",
13
+ destructive:
14
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15
+ outline:
16
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17
+ secondary:
18
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
+ ghost: "hover:bg-accent hover:text-accent-foreground",
20
+ link: "text-primary underline-offset-4 hover:underline",
21
+ },
22
+ size: {
23
+ default: "h-10 px-4 py-2",
24
+ sm: "h-9 rounded-md px-3",
25
+ lg: "h-11 rounded-md px-8",
26
+ icon: "h-10 w-10",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: "default",
31
+ size: "default",
32
+ },
33
+ }
34
+ );
35
+
36
+ export interface ButtonProps
37
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38
+ VariantProps<typeof buttonVariants> {
39
+ asChild?: boolean;
40
+ }
41
+
42
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
44
+ const Comp = asChild ? Slot : "button";
45
+ return (
46
+ <Comp
47
+ className={cn(buttonVariants({ variant, size, className }))}
48
+ ref={ref}
49
+ {...props}
50
+ />
51
+ );
52
+ }
53
+ );
54
+ Button.displayName = "Button";
55
+
56
+ export { Button, buttonVariants };