create-freakpunch 0.0.0-stage → 0.2.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 (216) hide show
  1. package/README.md +24 -3
  2. package/bin/create-freakpunch.mjs +227 -0
  3. package/files/README.md +19 -0
  4. package/files/app.config.ts +50 -0
  5. package/files/locales.ts +10 -0
  6. package/files/registry.ts +17 -0
  7. package/package.json +23 -6
  8. package/template/.dockerignore +17 -0
  9. package/template/.oxlintrc.json +9 -0
  10. package/template/AGENTS.md +6 -0
  11. package/template/BACKEND.md +108 -0
  12. package/template/CLAUDE.md +297 -0
  13. package/template/Dockerfile +19 -0
  14. package/template/_gitignore +26 -0
  15. package/template/components.json +27 -0
  16. package/template/design/COMPONENTS.md +145 -0
  17. package/template/design/DESIGN.md +212 -0
  18. package/template/design/PATTERNS.md +110 -0
  19. package/template/index.html +25 -0
  20. package/template/nginx.conf +32 -0
  21. package/template/package-lock.json +6484 -0
  22. package/template/package.json +51 -0
  23. package/template/public/favicon.svg +1 -0
  24. package/template/public/robots.txt +2 -0
  25. package/template/src/app.config.ts +50 -0
  26. package/template/src/app.roles.ts +24 -0
  27. package/template/src/components/ui/alert-dialog.tsx +181 -0
  28. package/template/src/components/ui/avatar.tsx +116 -0
  29. package/template/src/components/ui/badge.tsx +57 -0
  30. package/template/src/components/ui/breadcrumb.tsx +130 -0
  31. package/template/src/components/ui/button.tsx +58 -0
  32. package/template/src/components/ui/calendar.tsx +277 -0
  33. package/template/src/components/ui/card.tsx +99 -0
  34. package/template/src/components/ui/chart.tsx +370 -0
  35. package/template/src/components/ui/checkbox.tsx +28 -0
  36. package/template/src/components/ui/combobox.tsx +329 -0
  37. package/template/src/components/ui/command.tsx +191 -0
  38. package/template/src/components/ui/dialog.tsx +162 -0
  39. package/template/src/components/ui/dropdown-menu.tsx +271 -0
  40. package/template/src/components/ui/empty.tsx +103 -0
  41. package/template/src/components/ui/field.tsx +236 -0
  42. package/template/src/components/ui/input-group.tsx +263 -0
  43. package/template/src/components/ui/input.tsx +45 -0
  44. package/template/src/components/ui/kbd.tsx +31 -0
  45. package/template/src/components/ui/label.tsx +17 -0
  46. package/template/src/components/ui/pagination.tsx +134 -0
  47. package/template/src/components/ui/popover.tsx +87 -0
  48. package/template/src/components/ui/radio-group.tsx +35 -0
  49. package/template/src/components/ui/select.tsx +204 -0
  50. package/template/src/components/ui/separator.tsx +25 -0
  51. package/template/src/components/ui/sheet.tsx +139 -0
  52. package/template/src/components/ui/sidebar.tsx +741 -0
  53. package/template/src/components/ui/skeleton.tsx +13 -0
  54. package/template/src/components/ui/sonner.tsx +78 -0
  55. package/template/src/components/ui/spinner.tsx +42 -0
  56. package/template/src/components/ui/switch.tsx +29 -0
  57. package/template/src/components/ui/table.tsx +121 -0
  58. package/template/src/components/ui/tabs.tsx +191 -0
  59. package/template/src/components/ui/textarea.tsx +17 -0
  60. package/template/src/components/ui/toggle-group.tsx +94 -0
  61. package/template/src/components/ui/toggle.tsx +48 -0
  62. package/template/src/components/ui/tooltip.tsx +91 -0
  63. package/template/src/core/api/demo.ts +8 -0
  64. package/template/src/core/api/http.ts +76 -0
  65. package/template/src/core/api/mock.ts +88 -0
  66. package/template/src/core/api/rest.ts +67 -0
  67. package/template/src/core/api/types.ts +21 -0
  68. package/template/src/core/audit/audit.service.ts +94 -0
  69. package/template/src/core/audit/hooks.ts +19 -0
  70. package/template/src/core/auth/auth-store.ts +52 -0
  71. package/template/src/core/auth/auth.service.ts +86 -0
  72. package/template/src/core/auth/can.tsx +39 -0
  73. package/template/src/core/auth/dev-role-switcher.tsx +64 -0
  74. package/template/src/core/auth/local-credentials.ts +46 -0
  75. package/template/src/core/auth/permissions.ts +115 -0
  76. package/template/src/core/auth/require-auth.tsx +16 -0
  77. package/template/src/core/auth/require-permission.tsx +24 -0
  78. package/template/src/core/auth/roles.ts +9 -0
  79. package/template/src/core/auth/types.ts +20 -0
  80. package/template/src/core/auth/use-auth.ts +19 -0
  81. package/template/src/core/company/company.service.ts +94 -0
  82. package/template/src/core/company/hooks.ts +40 -0
  83. package/template/src/core/company/password-policy.ts +40 -0
  84. package/template/src/core/company/types.ts +46 -0
  85. package/template/src/core/company/use-app-name.ts +7 -0
  86. package/template/src/core/components/button-link.tsx +14 -0
  87. package/template/src/core/components/confirm-dialog.tsx +116 -0
  88. package/template/src/core/components/data-table/data-table.tsx +297 -0
  89. package/template/src/core/components/data-table/features.ts +24 -0
  90. package/template/src/core/components/data-table/table-header-cell.tsx +13 -0
  91. package/template/src/core/components/data-table/toolbar.tsx +100 -0
  92. package/template/src/core/components/data-table/use-list-url-state.ts +108 -0
  93. package/template/src/core/components/date-picker.tsx +71 -0
  94. package/template/src/core/components/file-attachments.tsx +84 -0
  95. package/template/src/core/components/form-error.tsx +9 -0
  96. package/template/src/core/components/form-page.tsx +93 -0
  97. package/template/src/core/components/image-upload.tsx +86 -0
  98. package/template/src/core/components/page.tsx +75 -0
  99. package/template/src/core/components/phone-input.tsx +58 -0
  100. package/template/src/core/components/search-select.tsx +57 -0
  101. package/template/src/core/components/segmented.tsx +41 -0
  102. package/template/src/core/components/states.tsx +97 -0
  103. package/template/src/core/components/status-badge.tsx +26 -0
  104. package/template/src/core/components/user-avatar.tsx +23 -0
  105. package/template/src/core/config/runtime.ts +16 -0
  106. package/template/src/core/config/types.ts +37 -0
  107. package/template/src/core/i18n/i18n.ts +69 -0
  108. package/template/src/core/i18n/i18next.d.ts +12 -0
  109. package/template/src/core/i18n/keys.ts +37 -0
  110. package/template/src/core/i18n/language-switcher.tsx +45 -0
  111. package/template/src/core/i18n/types.ts +17 -0
  112. package/template/src/core/i18n/use-format.ts +31 -0
  113. package/template/src/core/layout/app-shell.tsx +50 -0
  114. package/template/src/core/layout/app-sidebar.tsx +285 -0
  115. package/template/src/core/layout/command-menu.tsx +117 -0
  116. package/template/src/core/layout/top-bar.tsx +100 -0
  117. package/template/src/core/lib/csv.ts +27 -0
  118. package/template/src/core/lib/format.ts +87 -0
  119. package/template/src/core/lib/phone.ts +50 -0
  120. package/template/src/core/lib/storage.ts +27 -0
  121. package/template/src/core/modules/lazy-page.ts +9 -0
  122. package/template/src/core/modules/navigation.ts +39 -0
  123. package/template/src/core/modules/types.ts +55 -0
  124. package/template/src/core/notifications/hooks.ts +84 -0
  125. package/template/src/core/notifications/notification-center.tsx +251 -0
  126. package/template/src/core/notifications/notifications.service.ts +132 -0
  127. package/template/src/core/notifications/types.ts +70 -0
  128. package/template/src/core/preferences/preferences-store.ts +70 -0
  129. package/template/src/core/setup/setup-gate.tsx +20 -0
  130. package/template/src/core/setup/setup.service.ts +101 -0
  131. package/template/src/core/theme/brand-context.tsx +53 -0
  132. package/template/src/core/theme/brand.ts +29 -0
  133. package/template/src/core/theme/theme-context.tsx +62 -0
  134. package/template/src/core/theme/theme-options.ts +8 -0
  135. package/template/src/core/theme/theme-toggle.tsx +45 -0
  136. package/template/src/core/users/hooks.ts +51 -0
  137. package/template/src/core/users/types.ts +37 -0
  138. package/template/src/core/users/users.service.ts +167 -0
  139. package/template/src/hooks/use-mobile.ts +19 -0
  140. package/template/src/index.css +321 -0
  141. package/template/src/lib/utils.ts +1 -0
  142. package/template/src/locales/en/account.ts +180 -0
  143. package/template/src/locales/en/auth.ts +18 -0
  144. package/template/src/locales/en/common.ts +151 -0
  145. package/template/src/locales/en/company.ts +380 -0
  146. package/template/src/locales/en/dashboard.ts +46 -0
  147. package/template/src/locales/en/errors.ts +18 -0
  148. package/template/src/locales/en/notifications.ts +43 -0
  149. package/template/src/locales/en/settings.ts +25 -0
  150. package/template/src/locales/en/setup.ts +45 -0
  151. package/template/src/locales/index.ts +58 -0
  152. package/template/src/locales/tr/account.ts +184 -0
  153. package/template/src/locales/tr/auth.ts +22 -0
  154. package/template/src/locales/tr/common.ts +154 -0
  155. package/template/src/locales/tr/company.ts +384 -0
  156. package/template/src/locales/tr/dashboard.ts +50 -0
  157. package/template/src/locales/tr/errors.ts +22 -0
  158. package/template/src/locales/tr/notifications.ts +47 -0
  159. package/template/src/locales/tr/settings.ts +29 -0
  160. package/template/src/locales/tr/setup.ts +49 -0
  161. package/template/src/main.tsx +16 -0
  162. package/template/src/modules/locales.ts +10 -0
  163. package/template/src/modules/registry.ts +17 -0
  164. package/template/src/pages/dashboard/dashboard-page.tsx +55 -0
  165. package/template/src/pages/dashboard/quick-actions.tsx +37 -0
  166. package/template/src/pages/login-page.tsx +152 -0
  167. package/template/src/pages/no-access-page.tsx +11 -0
  168. package/template/src/pages/not-found-page.tsx +61 -0
  169. package/template/src/pages/settings/account/account.service.ts +128 -0
  170. package/template/src/pages/settings/account/components/mock-qr.tsx +50 -0
  171. package/template/src/pages/settings/account/components/password-strength.tsx +38 -0
  172. package/template/src/pages/settings/account/components/two-factor-dialog.tsx +140 -0
  173. package/template/src/pages/settings/account/hooks.ts +73 -0
  174. package/template/src/pages/settings/account/notifications-page.tsx +103 -0
  175. package/template/src/pages/settings/account/preferences-page.tsx +157 -0
  176. package/template/src/pages/settings/account/profile-page.tsx +242 -0
  177. package/template/src/pages/settings/account/security-page.tsx +364 -0
  178. package/template/src/pages/settings/account/types.ts +37 -0
  179. package/template/src/pages/settings/company/audit-log-page.tsx +126 -0
  180. package/template/src/pages/settings/company/branding-page.tsx +278 -0
  181. package/template/src/pages/settings/company/components/invite-dialog.tsx +106 -0
  182. package/template/src/pages/settings/company/components/read-only-notice.tsx +13 -0
  183. package/template/src/pages/settings/company/danger-zone-page.tsx +127 -0
  184. package/template/src/pages/settings/company/general-page.tsx +234 -0
  185. package/template/src/pages/settings/company/integrations/api-keys-panel.tsx +170 -0
  186. package/template/src/pages/settings/company/integrations/hooks.ts +37 -0
  187. package/template/src/pages/settings/company/integrations/integrations-page.tsx +57 -0
  188. package/template/src/pages/settings/company/integrations/integrations.service.ts +153 -0
  189. package/template/src/pages/settings/company/integrations/settings-forms.tsx +299 -0
  190. package/template/src/pages/settings/company/integrations/webhooks-panel.tsx +179 -0
  191. package/template/src/pages/settings/company/modules-page.tsx +65 -0
  192. package/template/src/pages/settings/company/roles-page.tsx +116 -0
  193. package/template/src/pages/settings/company/security-policies-page.tsx +164 -0
  194. package/template/src/pages/settings/company/users-page.tsx +262 -0
  195. package/template/src/pages/settings/settings-layout.tsx +57 -0
  196. package/template/src/pages/settings/settings-nav.ts +69 -0
  197. package/template/src/pages/settings/settings-routes.tsx +49 -0
  198. package/template/src/pages/setup-page.tsx +387 -0
  199. package/template/src/providers.tsx +68 -0
  200. package/template/src/router.tsx +59 -0
  201. package/template/tools/check-design.mjs +73 -0
  202. package/template/tools/new-module.mjs +90 -0
  203. package/template/tools/templates/module/api/__id__.mock.ts.tpl +17 -0
  204. package/template/tools/templates/module/api/__id__.service.ts.tpl +51 -0
  205. package/template/tools/templates/module/hooks.ts.tpl +57 -0
  206. package/template/tools/templates/module/index.ts.tpl +44 -0
  207. package/template/tools/templates/module/locales/en.ts.tpl +51 -0
  208. package/template/tools/templates/module/locales/tr.ts.tpl +55 -0
  209. package/template/tools/templates/module/pages/__id__-detail-page.tsx.tpl +103 -0
  210. package/template/tools/templates/module/pages/__id__-form-page.tsx.tpl +121 -0
  211. package/template/tools/templates/module/pages/__id__-list-page.tsx.tpl +234 -0
  212. package/template/tools/templates/module/types.ts.tpl +32 -0
  213. package/template/tsconfig.app.json +32 -0
  214. package/template/tsconfig.json +12 -0
  215. package/template/tsconfig.node.json +23 -0
  216. package/template/vite.config.ts +47 -0
@@ -0,0 +1,277 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+ import {
6
+ DayPicker,
7
+ getDefaultClassNames,
8
+ type ChevronProps,
9
+ type DayButton,
10
+ type Locale,
11
+ type RootProps,
12
+ type WeekNumberProps,
13
+ } from "react-day-picker"
14
+
15
+ import { Button, buttonVariants } from "@/components/ui/button"
16
+ import {
17
+ ChevronLeftIcon,
18
+ ChevronRightIcon,
19
+ ChevronDownIcon,
20
+ } from "lucide-react"
21
+
22
+ function Calendar({
23
+ className,
24
+ classNames,
25
+ showOutsideDays = true,
26
+ captionLayout = "label",
27
+ buttonVariant = "ghost",
28
+ locale,
29
+ formatters,
30
+ components,
31
+ numberOfMonths = 1,
32
+ ...props
33
+ }: React.ComponentProps<typeof DayPicker> & {
34
+ buttonVariant?: React.ComponentProps<typeof Button>["variant"]
35
+ }) {
36
+ const defaultClassNames = getDefaultClassNames()
37
+ const rootWidth =
38
+ numberOfMonths <= 1
39
+ ? "w-64"
40
+ : numberOfMonths === 2
41
+ ? "w-64 md:w-128"
42
+ : "w-fit"
43
+
44
+ const LocalizedDayButton = React.useCallback(
45
+ (dayButtonProps: React.ComponentProps<typeof DayButton>) => (
46
+ <CalendarDayButton locale={locale} {...dayButtonProps} />
47
+ ),
48
+ [locale]
49
+ )
50
+
51
+ const mergedComponents = React.useMemo(
52
+ () => ({
53
+ Root: CalendarRoot,
54
+ Chevron: CalendarChevron,
55
+ DayButton: LocalizedDayButton,
56
+ WeekNumber: CalendarWeekNumber,
57
+ ...components,
58
+ }),
59
+ [LocalizedDayButton, components]
60
+ )
61
+
62
+ return (
63
+ <DayPicker
64
+ showOutsideDays={showOutsideDays}
65
+ numberOfMonths={numberOfMonths}
66
+ className={cn(
67
+ "group/calendar max-w-full bg-background p-3 [--cell-radius:var(--radius-sm)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
68
+ rootWidth,
69
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
70
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
71
+ className
72
+ )}
73
+ captionLayout={captionLayout}
74
+ locale={locale}
75
+ formatters={formatters}
76
+ classNames={{
77
+ root: defaultClassNames.root,
78
+ months: cn(
79
+ "relative flex flex-col gap-6 md:flex-row",
80
+ defaultClassNames.months
81
+ ),
82
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
83
+ nav: cn(
84
+ "absolute top-0 right-0 flex h-6 items-center gap-1",
85
+ defaultClassNames.nav
86
+ ),
87
+ button_previous: cn(
88
+ buttonVariants({ variant: buttonVariant }),
89
+ "size-6 p-0 select-none aria-disabled:opacity-50",
90
+ defaultClassNames.button_previous
91
+ ),
92
+ button_next: cn(
93
+ buttonVariants({ variant: buttonVariant }),
94
+ "size-6 p-0 select-none aria-disabled:opacity-50",
95
+ defaultClassNames.button_next
96
+ ),
97
+ month_caption: cn(
98
+ "flex h-6 w-full items-center justify-start pr-13",
99
+ defaultClassNames.month_caption
100
+ ),
101
+ dropdowns: cn(
102
+ "flex h-6 w-full items-center justify-start gap-2 pr-13 text-sm font-normal",
103
+ defaultClassNames.dropdowns
104
+ ),
105
+ dropdown_root: cn(
106
+ "relative rounded-(--cell-radius)",
107
+ defaultClassNames.dropdown_root
108
+ ),
109
+ dropdown: cn(
110
+ "absolute inset-0 bg-popover opacity-0",
111
+ defaultClassNames.dropdown
112
+ ),
113
+ caption_label: cn(
114
+ "font-normal select-none",
115
+ captionLayout === "label"
116
+ ? "text-sm"
117
+ : "flex items-center gap-0.5 rounded-(--cell-radius) text-sm [&>svg]:size-4 [&>svg]:text-muted-foreground",
118
+ defaultClassNames.caption_label
119
+ ),
120
+ month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
121
+ weekdays: cn("flex", defaultClassNames.weekdays),
122
+ weekday: cn(
123
+ "flex-1 rounded-sm py-0.5 text-sm font-normal text-muted-foreground select-none",
124
+ defaultClassNames.weekday
125
+ ),
126
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
127
+ week_number_header: cn(
128
+ "w-(--cell-size) select-none",
129
+ defaultClassNames.week_number_header
130
+ ),
131
+ week_number: cn(
132
+ "text-[0.8rem] text-muted-foreground select-none",
133
+ defaultClassNames.week_number
134
+ ),
135
+ day: cn(
136
+ "group/day relative h-(--cell-size) w-full min-w-(--cell-size) rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
137
+ props.showWeekNumber
138
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)"
139
+ : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
140
+ defaultClassNames.day
141
+ ),
142
+ range_start: cn(
143
+ "relative isolate z-0 rounded-l-(--cell-radius) bg-fill-2 after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-fill-2",
144
+ defaultClassNames.range_start
145
+ ),
146
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
147
+ range_end: cn(
148
+ "relative isolate z-0 rounded-r-(--cell-radius) bg-fill-2 after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-fill-2",
149
+ defaultClassNames.range_end
150
+ ),
151
+ today: cn(
152
+ "rounded-(--cell-radius) bg-fill-2 text-foreground data-[selected=true]:rounded-none",
153
+ defaultClassNames.today
154
+ ),
155
+ outside: cn(
156
+ "text-muted-foreground aria-selected:text-muted-foreground",
157
+ defaultClassNames.outside
158
+ ),
159
+ disabled: cn(
160
+ "text-muted-foreground opacity-50",
161
+ defaultClassNames.disabled
162
+ ),
163
+ hidden: cn("invisible", defaultClassNames.hidden),
164
+ ...classNames,
165
+ }}
166
+ components={mergedComponents}
167
+ {...props}
168
+ />
169
+ )
170
+ }
171
+
172
+ function CalendarRoot({ className, rootRef, ...props }: RootProps) {
173
+ return (
174
+ <div
175
+ data-slot="calendar"
176
+ ref={rootRef}
177
+ className={className}
178
+ {...props}
179
+ />
180
+ )
181
+ }
182
+
183
+ function CalendarChevron({
184
+ className,
185
+ orientation,
186
+ size,
187
+ style,
188
+ }: ChevronProps) {
189
+ if (orientation === "left") {
190
+ return (
191
+ <ChevronLeftIcon
192
+ className={cn("size-4", className)}
193
+ size={size}
194
+ style={style}
195
+ />
196
+ )
197
+ }
198
+
199
+ if (orientation === "right") {
200
+ return (
201
+ <ChevronRightIcon
202
+ className={cn("size-4", className)}
203
+ size={size}
204
+ style={style}
205
+ />
206
+ )
207
+ }
208
+
209
+ return (
210
+ <ChevronDownIcon
211
+ className={cn("size-4", className)}
212
+ size={size}
213
+ style={style}
214
+ />
215
+ )
216
+ }
217
+
218
+ function CalendarWeekNumber({
219
+ children,
220
+ className,
221
+ style,
222
+ role,
223
+ scope,
224
+ "aria-label": ariaLabel,
225
+ }: WeekNumberProps) {
226
+ return (
227
+ <td
228
+ className={className}
229
+ style={style}
230
+ role={role}
231
+ scope={scope}
232
+ aria-label={ariaLabel}
233
+ >
234
+ <div className="flex size-(--cell-size) items-center justify-center text-center">
235
+ {children}
236
+ </div>
237
+ </td>
238
+ )
239
+ }
240
+
241
+ function CalendarDayButton({
242
+ className,
243
+ day,
244
+ modifiers,
245
+ locale,
246
+ ...props
247
+ }: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {
248
+ const ref = React.useRef<HTMLButtonElement>(null)
249
+ React.useEffect(() => {
250
+ if (modifiers.focused) ref.current?.focus()
251
+ }, [modifiers.focused])
252
+
253
+ return (
254
+ <Button
255
+ ref={ref}
256
+ variant="ghost"
257
+ size="icon"
258
+ data-day={day.date.toLocaleDateString(locale?.code ?? "en-US")}
259
+ data-selected-single={
260
+ modifiers.selected &&
261
+ !modifiers.range_start &&
262
+ !modifiers.range_end &&
263
+ !modifiers.range_middle
264
+ }
265
+ data-range-start={modifiers.range_start}
266
+ data-range-end={modifiers.range_end}
267
+ data-range-middle={modifiers.range_middle}
268
+ className={cn(
269
+ "relative isolate z-10 flex h-full w-full min-w-(--cell-size) flex-col gap-1 rounded-(--cell-radius) leading-none font-normal group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/30 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-fill-2 data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-2xs [&>span]:opacity-70",
270
+ className
271
+ )}
272
+ {...props}
273
+ />
274
+ )
275
+ }
276
+
277
+ export { Calendar, CalendarDayButton }
@@ -0,0 +1,99 @@
1
+ import * as React from "react"
2
+ import { cn } from "@/lib/utils"
3
+
4
+ function Card({
5
+ className,
6
+ size = "default",
7
+ ...props
8
+ }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
9
+ return (
10
+ <div
11
+ data-slot="card"
12
+ data-size={size}
13
+ className={cn(
14
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-3xl bg-card py-(--card-spacing) text-sm text-card-foreground shadow-(--shadow-card) ring-1 ring-border [--card-spacing:--spacing(5)] has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(4)] *:[img:first-child]:rounded-t-3xl *:[img:last-child]:rounded-b-3xl",
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
23
+ return (
24
+ <div
25
+ data-slot="card-header"
26
+ className={cn(
27
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-x-3 gap-y-1.5 rounded-t-3xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
28
+ className
29
+ )}
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
36
+ return (
37
+ <div
38
+ data-slot="card-title"
39
+ className={cn("font-heading text-base font-medium", className)}
40
+ {...props}
41
+ />
42
+ )
43
+ }
44
+
45
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
46
+ return (
47
+ <div
48
+ data-slot="card-description"
49
+ className={cn("text-sm text-muted-foreground", className)}
50
+ {...props}
51
+ />
52
+ )
53
+ }
54
+
55
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
56
+ return (
57
+ <div
58
+ data-slot="card-action"
59
+ className={cn(
60
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
69
+ return (
70
+ <div
71
+ data-slot="card-content"
72
+ className={cn("px-(--card-spacing)", className)}
73
+ {...props}
74
+ />
75
+ )
76
+ }
77
+
78
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
79
+ return (
80
+ <div
81
+ data-slot="card-footer"
82
+ className={cn(
83
+ "flex items-center gap-2 rounded-b-3xl px-(--card-spacing) [.border-t]:pt-(--card-spacing)",
84
+ className
85
+ )}
86
+ {...props}
87
+ />
88
+ )
89
+ }
90
+
91
+ export {
92
+ Card,
93
+ CardHeader,
94
+ CardFooter,
95
+ CardTitle,
96
+ CardAction,
97
+ CardDescription,
98
+ CardContent,
99
+ }