betterstart-cli 0.0.22 → 0.0.23

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 (92) hide show
  1. package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar-branding-skeleton.tsx +1 -1
  2. package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar-user-menu-skeleton.tsx +1 -1
  3. package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar-user-menu.tsx +1 -1
  4. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/lifecycle-hooks-tab.tsx +2 -2
  5. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/snippets-tab.tsx +1 -1
  6. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-version-item.tsx +1 -1
  7. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-versions-current-row.tsx +1 -1
  8. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-versions-drawer.tsx +3 -3
  9. package/dist/assets/adapters/next/templates/init/components/shared/media/edit-media-dialog-content.tsx +2 -2
  10. package/dist/assets/adapters/next/templates/init/components/shared/media/media-delete-drawer.tsx +3 -3
  11. package/dist/assets/adapters/next/templates/init/components/shared/media/media-gallery-dialog.tsx +62 -64
  12. package/dist/assets/adapters/next/templates/init/components/shared/media/media-grid-item.tsx +1 -1
  13. package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx +1 -1
  14. package/dist/assets/adapters/next/templates/init/data/navigation.ts +1 -3
  15. package/dist/assets/adapters/next/templates/init/lib/actions/auth/auth.ts +8 -0
  16. package/dist/assets/adapters/next/templates/init/lib/actions/profile/change-own-password.ts +59 -0
  17. package/dist/assets/adapters/next/templates/init/lib/actions/profile/index.ts +6 -1
  18. package/dist/assets/adapters/next/templates/init/lib/actions/profile/types.ts +10 -0
  19. package/dist/assets/adapters/next/templates/init/lib/actions/users/change-user-password.ts +77 -0
  20. package/dist/assets/adapters/next/templates/init/lib/actions/users/index.ts +3 -0
  21. package/dist/assets/adapters/next/templates/init/lib/actions/users/types.ts +10 -0
  22. package/dist/assets/adapters/next/templates/init/lib/db/core/schema.ts +4 -0
  23. package/dist/assets/adapters/next/templates/init/pages/dashboard-page.tsx +1 -1
  24. package/dist/assets/adapters/next/templates/init/pages/forgot-password-page-skeleton.tsx +1 -1
  25. package/dist/assets/adapters/next/templates/init/pages/login-page-skeleton.tsx +1 -1
  26. package/dist/assets/adapters/next/templates/init/pages/media/media-page-content.tsx +13 -18
  27. package/dist/assets/adapters/next/templates/init/pages/profile/profile-form.tsx +133 -1
  28. package/dist/assets/adapters/next/templates/init/pages/reset-password-page-skeleton.tsx +1 -1
  29. package/dist/assets/adapters/next/templates/init/pages/users/change-password-dialog.tsx +229 -0
  30. package/dist/assets/adapters/next/templates/init/pages/users/columns.tsx +22 -14
  31. package/dist/assets/adapters/next/templates/init/pages/users/create-user-dialog.tsx +99 -93
  32. package/dist/assets/adapters/next/templates/init/pages/users/delete-user-dialog.tsx +17 -25
  33. package/dist/assets/adapters/next/templates/init/pages/users/users-table.tsx +5 -4
  34. package/dist/assets/shared-assets/react-admin/custom/content-editor/math-bubble-menu.tsx +1 -1
  35. package/dist/assets/shared-assets/react-admin/custom/content-editor/remove-table-part-icon.tsx +1 -1
  36. package/dist/assets/shared-assets/react-admin/custom/content-editor/selection-bubble-menu.tsx +2 -2
  37. package/dist/assets/shared-assets/react-admin/custom/content-editor/table-bubble-menu.tsx +1 -1
  38. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-button/color-highlight-button.tsx +2 -2
  39. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/color-highlight-popover-content.tsx +1 -1
  40. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx +1 -1
  41. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/highlight-color-button.tsx +2 -2
  42. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/source-color-highlight-popover.tsx +1 -1
  43. package/dist/assets/shared-assets/react-admin/custom/date-range-picker.tsx +1 -1
  44. package/dist/assets/shared-assets/react-admin/custom/media-field-empty-state.tsx +19 -12
  45. package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +2 -2
  46. package/dist/assets/shared-assets/react-admin/custom/nested-object-list-field.tsx +1 -1
  47. package/dist/assets/shared-assets/react-admin/custom/placeholder-card.tsx +1 -1
  48. package/dist/assets/shared-assets/react-admin/custom/placeholder.tsx +1 -1
  49. package/dist/assets/shared-assets/react-admin/ui/accordion.tsx +1 -1
  50. package/dist/assets/shared-assets/react-admin/ui/alert-dialog.tsx +15 -4
  51. package/dist/assets/shared-assets/react-admin/ui/alert.tsx +1 -1
  52. package/dist/assets/shared-assets/react-admin/ui/avatar.tsx +5 -5
  53. package/dist/assets/shared-assets/react-admin/ui/badge.tsx +1 -1
  54. package/dist/assets/shared-assets/react-admin/ui/button-group.tsx +3 -3
  55. package/dist/assets/shared-assets/react-admin/ui/button.tsx +6 -6
  56. package/dist/assets/shared-assets/react-admin/ui/card.tsx +4 -4
  57. package/dist/assets/shared-assets/react-admin/ui/carousel.tsx +2 -2
  58. package/dist/assets/shared-assets/react-admin/ui/chart.tsx +1 -1
  59. package/dist/assets/shared-assets/react-admin/ui/combobox.tsx +4 -4
  60. package/dist/assets/shared-assets/react-admin/ui/command.tsx +3 -3
  61. package/dist/assets/shared-assets/react-admin/ui/context-menu.tsx +6 -6
  62. package/dist/assets/shared-assets/react-admin/ui/dialog.tsx +29 -6
  63. package/dist/assets/shared-assets/react-admin/ui/drawer.tsx +2 -2
  64. package/dist/assets/shared-assets/react-admin/ui/dropdown-menu.tsx +6 -6
  65. package/dist/assets/shared-assets/react-admin/ui/empty.tsx +2 -2
  66. package/dist/assets/shared-assets/react-admin/ui/field.tsx +1 -1
  67. package/dist/assets/shared-assets/react-admin/ui/hover-card.tsx +1 -1
  68. package/dist/assets/shared-assets/react-admin/ui/input-group.tsx +5 -6
  69. package/dist/assets/shared-assets/react-admin/ui/input-otp.tsx +2 -2
  70. package/dist/assets/shared-assets/react-admin/ui/input.tsx +1 -1
  71. package/dist/assets/shared-assets/react-admin/ui/item.tsx +2 -2
  72. package/dist/assets/shared-assets/react-admin/ui/menubar.tsx +8 -8
  73. package/dist/assets/shared-assets/react-admin/ui/native-select.tsx +1 -1
  74. package/dist/assets/shared-assets/react-admin/ui/navigation-menu.tsx +4 -4
  75. package/dist/assets/shared-assets/react-admin/ui/popover.tsx +1 -1
  76. package/dist/assets/shared-assets/react-admin/ui/progress.tsx +1 -1
  77. package/dist/assets/shared-assets/react-admin/ui/radio-group.tsx +2 -2
  78. package/dist/assets/shared-assets/react-admin/ui/resizable.tsx +1 -1
  79. package/dist/assets/shared-assets/react-admin/ui/scroll-area.tsx +1 -1
  80. package/dist/assets/shared-assets/react-admin/ui/select.tsx +3 -3
  81. package/dist/assets/shared-assets/react-admin/ui/sidebar.tsx +10 -10
  82. package/dist/assets/shared-assets/react-admin/ui/skeleton.tsx +1 -1
  83. package/dist/assets/shared-assets/react-admin/ui/slider.tsx +2 -2
  84. package/dist/assets/shared-assets/react-admin/ui/switch.tsx +2 -2
  85. package/dist/assets/shared-assets/react-admin/ui/tabs.tsx +3 -3
  86. package/dist/assets/shared-assets/react-admin/ui/textarea.tsx +1 -1
  87. package/dist/assets/shared-assets/react-admin/ui/toggle-group.tsx +2 -2
  88. package/dist/assets/shared-assets/react-admin/ui/toggle.tsx +1 -1
  89. package/dist/assets/shared-assets/react-admin/ui/tooltip.tsx +1 -1
  90. package/dist/cli.js +5372 -4243
  91. package/dist/cli.js.map +1 -1
  92. package/package.json +1 -1
@@ -4,6 +4,7 @@ import { createUser } from '@admin/actions/users'
4
4
  import { Button } from '@admin/components/ui/button'
5
5
  import {
6
6
  Dialog,
7
+ DialogBody,
7
8
  DialogContent,
8
9
  DialogDescription,
9
10
  DialogFooter,
@@ -111,102 +112,107 @@ export function CreateUserDialog() {
111
112
  <Button>Create User</Button>
112
113
  </DialogTrigger>
113
114
  <DialogContent className="sm:max-w-135">
114
- <DialogHeader>
115
- <DialogTitle>Create User</DialogTitle>
116
- <DialogDescription>Add a new user to the system</DialogDescription>
117
- </DialogHeader>
118
115
  <Form {...form}>
119
- <form
120
- onSubmit={form.handleSubmit((values) => mutation.mutate(values))}
121
- className="space-y-4"
122
- >
123
- <div className="space-y-4 px-2 pt-2 pb-4">
124
- <FormField
125
- control={form.control}
126
- name="email"
127
- render={({ field }) => (
128
- <FormItem>
129
- <FormLabel>Email</FormLabel>
130
- <FormControl>
131
- <Input
132
- type="email"
133
- placeholder="user@example.com"
134
- autoComplete="email"
135
- disabled={isPending}
136
- {...field}
137
- />
138
- </FormControl>
139
- <FormMessage />
140
- </FormItem>
141
- )}
142
- />
143
- <FormField
144
- control={form.control}
145
- name="name"
146
- render={({ field }) => (
147
- <FormItem>
148
- <FormLabel>Name</FormLabel>
149
- <FormControl>
150
- <Input
151
- type="text"
152
- placeholder="Full name"
153
- autoComplete="name"
154
- disabled={isPending}
155
- {...field}
156
- />
157
- </FormControl>
158
- <FormMessage />
159
- </FormItem>
160
- )}
161
- />
162
- <FormField
163
- control={form.control}
164
- name="password"
165
- render={({ field }) => (
166
- <FormItem>
167
- <FormLabel>Password</FormLabel>
168
- <FormControl>
169
- <Input
170
- type="password"
171
- placeholder="Min 8 characters"
172
- autoComplete="new-password"
173
- disabled={isPending}
174
- {...field}
175
- />
176
- </FormControl>
177
- <FormDescription>
178
- Use at least 8 characters for the temporary password.
179
- </FormDescription>
180
- <FormMessage />
181
- </FormItem>
182
- )}
183
- />
184
- <FormField
185
- control={form.control}
186
- name="role"
187
- render={({ field }) => (
188
- <FormItem>
189
- <FormLabel>Role</FormLabel>
190
- <Select value={field.value} onValueChange={field.onChange} disabled={isPending}>
116
+ <form onSubmit={form.handleSubmit((values) => mutation.mutate(values))}>
117
+ <DialogHeader>
118
+ <DialogTitle>Create User</DialogTitle>
119
+ <DialogDescription>Add a new user to the system</DialogDescription>
120
+ </DialogHeader>
121
+
122
+ <DialogBody>
123
+ <div className="space-y-4">
124
+ <FormField
125
+ control={form.control}
126
+ name="email"
127
+ render={({ field }) => (
128
+ <FormItem>
129
+ <FormLabel>Email</FormLabel>
130
+ <FormControl>
131
+ <Input
132
+ type="email"
133
+ placeholder="user@example.com"
134
+ autoComplete="email"
135
+ disabled={isPending}
136
+ {...field}
137
+ />
138
+ </FormControl>
139
+ <FormMessage />
140
+ </FormItem>
141
+ )}
142
+ />
143
+ <FormField
144
+ control={form.control}
145
+ name="name"
146
+ render={({ field }) => (
147
+ <FormItem>
148
+ <FormLabel>Name</FormLabel>
149
+ <FormControl>
150
+ <Input
151
+ type="text"
152
+ placeholder="Full name"
153
+ autoComplete="name"
154
+ disabled={isPending}
155
+ {...field}
156
+ />
157
+ </FormControl>
158
+ <FormMessage />
159
+ </FormItem>
160
+ )}
161
+ />
162
+ <FormField
163
+ control={form.control}
164
+ name="password"
165
+ render={({ field }) => (
166
+ <FormItem>
167
+ <FormLabel>Password</FormLabel>
191
168
  <FormControl>
192
- <SelectTrigger className="w-full">
193
- <SelectValue placeholder="Select a role" />
194
- </SelectTrigger>
169
+ <Input
170
+ type="password"
171
+ placeholder="Min 8 characters"
172
+ autoComplete="new-password"
173
+ disabled={isPending}
174
+ {...field}
175
+ />
195
176
  </FormControl>
196
- <SelectContent>
197
- <SelectItem value={UserRole.ADMIN}>Admin</SelectItem>
198
- <SelectItem value={UserRole.EDITOR}>Editor</SelectItem>
199
- <SelectItem value={UserRole.MEMBER}>Member</SelectItem>
200
- </SelectContent>
201
- </Select>
202
- <FormDescription>
203
- Choose the access level the new user should start with.
204
- </FormDescription>
205
- <FormMessage />
206
- </FormItem>
207
- )}
208
- />
209
- </div>
177
+ <FormDescription>
178
+ Use at least 8 characters for the temporary password.
179
+ </FormDescription>
180
+ <FormMessage />
181
+ </FormItem>
182
+ )}
183
+ />
184
+ <FormField
185
+ control={form.control}
186
+ name="role"
187
+ render={({ field }) => (
188
+ <FormItem>
189
+ <FormLabel>Role</FormLabel>
190
+ <Select
191
+ value={field.value}
192
+ onValueChange={field.onChange}
193
+ disabled={isPending}
194
+ >
195
+ <FormControl>
196
+ <SelectTrigger className="w-full">
197
+ <SelectValue placeholder="Select a role" />
198
+ </SelectTrigger>
199
+ </FormControl>
200
+ <SelectContent>
201
+ <SelectItem value={UserRole.ADMIN}>Admin</SelectItem>
202
+ <SelectItem value={UserRole.EDITOR}>Editor</SelectItem>
203
+ <SelectItem value={UserRole.MEMBER}>Member</SelectItem>
204
+ </SelectContent>
205
+ </Select>
206
+ <FormDescription>
207
+ Choose the access level the new user should start with.
208
+ </FormDescription>
209
+ <FormMessage />
210
+ </FormItem>
211
+ )}
212
+ />
213
+ </div>
214
+ </DialogBody>
215
+
210
216
  <DialogFooter showCloseButton={true}>
211
217
  <Button type="submit" disabled={isPending} size="lg">
212
218
  {isPending && <LoaderCircle className="animate-spin" />}
@@ -3,6 +3,7 @@
3
3
  import { deleteUser } from '@admin/actions/users'
4
4
  import {
5
5
  AlertDialog,
6
+ AlertDialogBody,
6
7
  AlertDialogCancel,
7
8
  AlertDialogContent,
8
9
  AlertDialogDescription,
@@ -12,6 +13,7 @@ import {
12
13
  AlertDialogTrigger
13
14
  } from '@admin/components/ui/alert-dialog'
14
15
  import { Button } from '@admin/components/ui/button'
16
+ import { DropdownMenuItem } from '@admin/components/ui/dropdown-menu'
15
17
  import {
16
18
  Form,
17
19
  FormControl,
@@ -102,33 +104,23 @@ export function DeleteUserDialog({ userId, userName, isCurrentUser }: DeleteUser
102
104
  return (
103
105
  <AlertDialog open={open} onOpenChange={handleOpenChange}>
104
106
  <AlertDialogTrigger asChild>
105
- <Button
106
- variant="ghost"
107
- onSelect={(e) => e.preventDefault()}
108
- className="justify-between text-destructive hover:text-destructive"
109
- >
110
- <span>Delete user</span>
111
- <Trash />
112
- </Button>
107
+ <DropdownMenuItem variant="destructive" onSelect={(event) => event.preventDefault()}>
108
+ <Trash className="size-4" />
109
+ Delete user
110
+ </DropdownMenuItem>
113
111
  </AlertDialogTrigger>
114
112
  <AlertDialogContent>
115
- <AlertDialogHeader>
116
- <AlertDialogTitle>
117
- <Trash className="size-4 text-destructive" /> Delete {userName}
118
- &apos;s account?
119
- </AlertDialogTitle>
120
- <AlertDialogDescription>
121
- This will permanently delete <strong className="text-foreground">{userName}</strong> and{' '}
122
- <br />
123
- all of their data.
124
- </AlertDialogDescription>
125
- </AlertDialogHeader>
126
113
  <Form {...form}>
127
- <form
128
- onSubmit={form.handleSubmit(() => mutation.mutate())}
129
- className="flex flex-col gap-4"
130
- >
131
- <div className="px-2">
114
+ <form onSubmit={form.handleSubmit(() => mutation.mutate())}>
115
+ <AlertDialogHeader>
116
+ <AlertDialogTitle>Delete account?</AlertDialogTitle>
117
+ <AlertDialogDescription>
118
+ This will permanently delete <strong className="text-foreground">{userName}</strong>
119
+ &apos;s account and <br />
120
+ all of their data. This action cannot be undone.
121
+ </AlertDialogDescription>
122
+ </AlertDialogHeader>
123
+ <AlertDialogBody>
132
124
  <FormField
133
125
  control={form.control}
134
126
  name="confirmation"
@@ -149,7 +141,7 @@ export function DeleteUserDialog({ userId, userName, isCurrentUser }: DeleteUser
149
141
  </FormItem>
150
142
  )}
151
143
  />
152
- </div>
144
+ </AlertDialogBody>
153
145
  <AlertDialogFooter>
154
146
  <AlertDialogCancel type="button" size="lg" disabled={isPending}>
155
147
  Cancel
@@ -160,7 +160,7 @@ export function UsersTable<TValue>({
160
160
  return (
161
161
  <DataGridHead
162
162
  key={header.id}
163
- className="group/resize-header relative overflow-hidden"
163
+ className="group/resize-header relative overflow-hidden px-4"
164
164
  data-column-id={header.column.id}
165
165
  onMouseEnter={() => setHoveredColumnId(header.column.id)}
166
166
  onMouseLeave={() =>
@@ -204,7 +204,7 @@ export function UsersTable<TValue>({
204
204
  {isPending ? (
205
205
  <DataGridRow>
206
206
  <DataGridCell
207
- className="flex h-24 items-center justify-center text-center"
207
+ className="flex h-24 items-center justify-center text-center px-4"
208
208
  style={{ gridColumn: '1 / -1' }}
209
209
  >
210
210
  <div className="text-muted-foreground">Loading users...</div>
@@ -213,7 +213,7 @@ export function UsersTable<TValue>({
213
213
  ) : error ? (
214
214
  <DataGridRow>
215
215
  <DataGridCell
216
- className="flex h-24 items-center justify-center text-center"
216
+ className="flex h-24 items-center justify-center text-center px-4"
217
217
  style={{ gridColumn: '1 / -1' }}
218
218
  >
219
219
  <div className="text-destructive">Error: {error.message}</div>
@@ -232,6 +232,7 @@ export function UsersTable<TValue>({
232
232
  current === cell.column.id ? null : current
233
233
  )
234
234
  }
235
+ className="px-4"
235
236
  >
236
237
  {flexRender(cell.column.columnDef.cell, cell.getContext())}
237
238
  </DataGridCell>
@@ -241,7 +242,7 @@ export function UsersTable<TValue>({
241
242
  ) : (
242
243
  <DataGridRow>
243
244
  <DataGridCell
244
- className="flex h-24 items-center justify-center text-center"
245
+ className="flex h-24 items-center justify-center text-center px-4"
245
246
  style={{ gridColumn: '1 / -1' }}
246
247
  >
247
248
  No users found.
@@ -63,7 +63,7 @@ export function MathBubbleMenu({ editor }: { editor: Editor }) {
63
63
  role="toolbar"
64
64
  aria-label="Math formatting toolbar"
65
65
  className={cn(
66
- 'flex items-center gap-1 overflow-x-auto border-border rounded-lg border bg-popover p-0 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
66
+ 'flex items-center gap-1 overflow-x-auto border-border rounded-sm border bg-popover p-0 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
67
67
  'relative z-50'
68
68
  )}
69
69
  >
@@ -11,7 +11,7 @@ export function RemoveTablePartIcon({
11
11
  return (
12
12
  <span className="tiptap-button-icon relative inline-flex size-4 items-center justify-center">
13
13
  <Icon className="size-4" />
14
- <MinusIcon className="-right-1 -bottom-0.5 border border-border absolute size-3 rounded-full bg-card stroke-3" />
14
+ <MinusIcon className="-right-1 -bottom-0.5 border border-border absolute size-3 rounded-sm bg-card stroke-3" />
15
15
  </span>
16
16
  )
17
17
  }
@@ -72,7 +72,7 @@ export function SelectionBubbleMenu({ editor }: { editor: Editor }) {
72
72
  role="toolbar"
73
73
  aria-label="Link formatting toolbar"
74
74
  className={cn(
75
- 'flex items-center gap-1 overflow-x-auto border-border border bg-popover p-4 text-foreground shadow-2xl [scrollbar-width:none] [&::-webkit-scrollbar]:hidden rounded-lg',
75
+ 'flex items-center gap-1 overflow-x-auto border-border border bg-popover p-4 text-foreground shadow-2xl [scrollbar-width:none] [&::-webkit-scrollbar]:hidden rounded-sm',
76
76
  'relative z-10'
77
77
  )}
78
78
  >
@@ -101,7 +101,7 @@ export function SelectionBubbleMenu({ editor }: { editor: Editor }) {
101
101
  aria-label="Selection formatting toolbar"
102
102
  onPointerDownCapture={handleSelectionMenuPointerDown}
103
103
  className={cn(
104
- 'flex items-center gap-1 overflow-x-auto border-border rounded-full border bg-popover p-1 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
104
+ 'flex items-center gap-1 overflow-x-auto border-border rounded-sm border bg-popover p-1 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
105
105
  'relative z-10'
106
106
  )}
107
107
  >
@@ -202,7 +202,7 @@ export function TableBubbleMenu({ editor }: { editor: Editor }) {
202
202
  role="toolbar"
203
203
  aria-label="Table formatting toolbar"
204
204
  className={cn(
205
- 'flex items-center gap-1 overflow-x-auto border-border rounded-full border bg-popover p-1 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
205
+ 'flex items-center gap-1 overflow-x-auto border-border rounded-sm border bg-popover p-1 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
206
206
  'relative z-50'
207
207
  )}
208
208
  >
@@ -49,10 +49,10 @@ export function HighlightSwatch({ highlightColor }: { highlightColor: string })
49
49
  return (
50
50
  <span
51
51
  className={cn(
52
- 'relative -mx-[0.175rem] size-5 rounded-full transition-transform duration-200 ease-in-out',
52
+ 'relative -mx-[0.175rem] size-5 rounded-sm transition-transform duration-200 ease-in-out',
53
53
  'bg-[var(--highlight-color)]',
54
54
  'shadow-[inset_0_0_0_1px_var(--highlight-shadow),_0_1px_2px_var(--highlight-shadow-soft)]',
55
- "after:content-[''] after:absolute after:inset-0 after:box-border after:size-full after:rounded-full after:border after:opacity-0 after:transition-opacity after:duration-200 after:ease-in-out",
55
+ "after:content-[''] after:absolute after:inset-0 after:box-border after:size-full after:rounded-sm after:border after:opacity-0 after:transition-opacity after:duration-200 after:ease-in-out",
56
56
  'after:border-[var(--highlight-after-border)]',
57
57
  'group-data-[active-state=on]/highlight:scale-110',
58
58
  'group-data-[highlighted=true]/highlight:scale-110',
@@ -118,7 +118,7 @@ export function ColorHighlightPopoverContent(props: ColorHighlightPopoverContent
118
118
  role="menuitem"
119
119
  variant="ghost"
120
120
  size="icon-sm"
121
- className="rounded-full"
121
+ className="rounded-sm"
122
122
  data-highlighted={selectedIndex === colors.length}
123
123
  disabled={disabled}
124
124
  data-disabled={disabled}
@@ -91,7 +91,7 @@ export function ColorHighlightPopover({
91
91
  </PopoverTrigger>
92
92
  <PopoverContent
93
93
  aria-label="Highlight colors"
94
- className="w-auto max-w-[calc(100vw-2rem)] gap-0 p-0 rounded-full"
94
+ className="w-auto max-w-[calc(100vw-2rem)] gap-0 p-0 rounded-sm"
95
95
  >
96
96
  <ColorHighlightPopoverContent
97
97
  editor={editor}
@@ -38,7 +38,7 @@ export function HighlightColorButton({
38
38
  useColorValue={useColorValue}
39
39
  style={buttonStyle}
40
40
  size="icon-sm"
41
- className="rounded-full"
41
+ className="rounded-sm"
42
42
  />
43
43
  )
44
44
  }
@@ -48,7 +48,7 @@ export function HighlightColorButton({
48
48
  type="button"
49
49
  variant="ghost"
50
50
  size="icon-sm"
51
- className={cn('group/highlight rounded-full')}
51
+ className={cn('group/highlight rounded-sm')}
52
52
  disabled={disabled}
53
53
  data-disabled={disabled}
54
54
  aria-label={`${color.label} highlight color`}
@@ -50,7 +50,7 @@ export function SourceColorHighlightPopover({
50
50
  </PopoverTrigger>
51
51
  <PopoverContent
52
52
  aria-label="Highlight colors"
53
- className="w-auto max-w-[calc(100vw-2rem)] gap-0 p-0 rounded-full"
53
+ className="w-auto max-w-[calc(100vw-2rem)] gap-0 p-0 rounded-sm"
54
54
  >
55
55
  <ColorHighlightPopoverContent
56
56
  mode="source"
@@ -139,7 +139,7 @@ export function DateRangePicker({
139
139
  <ChevronDown />
140
140
  </Button>
141
141
  </PopoverTrigger>
142
- <PopoverContent className="w-[282px] gap-0 overflow-hidden rounded-lg p-0" align="start">
142
+ <PopoverContent className="w-[282px] gap-0 overflow-hidden rounded-sm p-0" align="start">
143
143
  <Calendar
144
144
  mode="range"
145
145
  month={calendarMonth}
@@ -9,22 +9,27 @@ import { ImageIcon } from 'lucide-react'
9
9
 
10
10
  interface MediaFieldEmptyStateProps {
11
11
  accept?: string
12
+ addButtonLabel?: string
12
13
  className?: string
13
14
  disabled?: boolean
15
+ isRemovable?: boolean
14
16
  mode?: 'single' | 'multi'
15
17
  open: boolean
16
18
  onOpenChange: (open: boolean) => void
17
19
  onSelect: (selected: AdminMedia | AdminMedia[]) => void
20
+ showAddButton?: boolean
18
21
  }
19
22
 
20
23
  export function MediaFieldEmptyState({
21
24
  accept,
25
+ addButtonLabel = 'Add Image',
22
26
  className,
23
27
  disabled,
24
28
  mode = 'single',
25
29
  open,
26
30
  onOpenChange,
27
- onSelect
31
+ onSelect,
32
+ showAddButton = true
28
33
  }: MediaFieldEmptyStateProps) {
29
34
  function handleAddImage(e: React.MouseEvent<HTMLButtonElement>) {
30
35
  e.preventDefault()
@@ -45,17 +50,19 @@ export function MediaFieldEmptyState({
45
50
  className="text-muted-foreground transition-opacity group-hover:opacity-0 group-focus-within:opacity-0"
46
51
  strokeWidth={1}
47
52
  />
48
- <div className="absolute inset-0 flex items-center justify-center gap-1 opacity-0 transition-opacity duration-200 ease-out group-hover:opacity-100 group-focus-within:opacity-100">
49
- <Button
50
- type="button"
51
- data-media-field-action="true"
52
- variant="outline"
53
- onClick={handleAddImage}
54
- className="border-primary/10"
55
- >
56
- Add Image
57
- </Button>
58
- </div>
53
+ {showAddButton ? (
54
+ <div className="absolute inset-0 flex items-center justify-center gap-1 opacity-0 transition-opacity duration-200 ease-out group-hover:opacity-100 group-focus-within:opacity-100">
55
+ <Button
56
+ type="button"
57
+ data-media-field-action="true"
58
+ variant="outline"
59
+ onClick={handleAddImage}
60
+ className="border-primary/10"
61
+ >
62
+ {addButtonLabel}
63
+ </Button>
64
+ </div>
65
+ ) : null}
59
66
  </CardContent>
60
67
  </Card>
61
68
 
@@ -85,7 +85,7 @@ export function MediaField({
85
85
  <CardContent className="p-0! relative">
86
86
  <div
87
87
  data-media-field-preview
88
- className="relative aspect-video rounded-lg bg-background overflow-hidden"
88
+ className="relative aspect-video rounded-sm bg-background overflow-hidden"
89
89
  >
90
90
  <MediaPreview media={selectedMedia} showMetadata={Boolean(media)} />
91
91
  </div>
@@ -94,7 +94,7 @@ export function MediaField({
94
94
  <>
95
95
  <div
96
96
  aria-hidden="true"
97
- className="pointer-events-none absolute inset-0 bg-black/10 opacity-0 backdrop-blur-xs transition-opacity duration-300 ease-out group-hover:opacity-100 rounded-lg"
97
+ className="pointer-events-none absolute inset-0 bg-black/10 opacity-0 backdrop-blur-xs transition-opacity duration-300 ease-out group-hover:opacity-100 rounded-sm"
98
98
  />
99
99
  <div className="absolute inset-0 flex flex-col items-center justify-center gap-1 opacity-0 transition-opacity duration-200 ease-out group-hover:opacity-100">
100
100
  <Button
@@ -197,7 +197,7 @@ export function NestedObjectListField({
197
197
  <X />
198
198
  </Button>
199
199
  </div>
200
- <AccordionContent className="space-y-5 border rounded-lg border-border p-5 bg-background mb-4">
200
+ <AccordionContent className="space-y-5 border rounded-sm border-border p-5 bg-background mb-4">
201
201
  {children(index)}
202
202
  </AccordionContent>
203
203
  </AccordionItem>
@@ -19,7 +19,7 @@ export function PlaceholderCard({
19
19
  return (
20
20
  <div
21
21
  className={cn(
22
- 'flex h-75 border border-border border-dashed bg-background flex-col items-center justify-center gap-5 rounded-lg',
22
+ 'flex h-75 border border-border border-dashed bg-background flex-col items-center justify-center gap-5 rounded-sm',
23
23
  className
24
24
  )}
25
25
  >
@@ -12,7 +12,7 @@ export function Placeholder({ label, description, action, className, ...props }:
12
12
  return (
13
13
  <div
14
14
  className={cn(
15
- 'border flex items-center flex-col gap-2 border-dashed border-border rounded-lg p-8 bg-background',
15
+ 'border flex items-center flex-col gap-2 border-dashed border-border rounded-sm p-8 bg-background',
16
16
  className
17
17
  )}
18
18
  {...props}
@@ -10,7 +10,7 @@ function Accordion({ className, ...props }: React.ComponentProps<typeof Accordio
10
10
  <AccordionPrimitive.Root
11
11
  data-slot="accordion"
12
12
  className={cn(
13
- 'flex w-full flex-col rounded-lg overflow-hidden border border-border bg-card shadow-2xl/1',
13
+ 'flex w-full flex-col rounded-sm overflow-hidden border border-border bg-card shadow-2xl/1',
14
14
  className
15
15
  )}
16
16
  {...props}
@@ -49,7 +49,7 @@ function AlertDialogContent({
49
49
  data-slot="alert-dialog-content"
50
50
  data-size={size}
51
51
  className={cn(
52
- 'group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-6 rounded-4xl bg-popover p-6 text-popover-foreground ring-1 ring-foreground/5 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-md data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
52
+ 'group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-6 rounded-sm bg-muted text-popover-foreground ring-1 ring-foreground/5 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-md data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 overflow-hidden',
53
53
  className
54
54
  )}
55
55
  {...props}
@@ -63,7 +63,7 @@ function AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>)
63
63
  <div
64
64
  data-slot="alert-dialog-header"
65
65
  className={cn(
66
- 'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]',
66
+ 'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr] bg-muted px-6 pt-6',
67
67
  className
68
68
  )}
69
69
  {...props}
@@ -71,11 +71,21 @@ function AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>)
71
71
  )
72
72
  }
73
73
 
74
+ function AlertDialogBody({ className, ...props }: React.ComponentProps<'div'>) {
75
+ return (
76
+ <div
77
+ data-slot="alert-dialog-body"
78
+ className={cn('flex shadow-input flex-col gap-1 px-6 py-6', className)}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
74
84
  function AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
75
85
  return (
76
86
  <div
77
87
  data-slot="alert-dialog-footer"
78
- className={cn('grid w-full grid-cols-2 gap-1 [&>*]:w-full', className)}
88
+ className={cn('grid w-full grid-cols-2 gap-1 px-6 pb-5 bg-muted *:w-full', className)}
79
89
  {...props}
80
90
  />
81
91
  )
@@ -86,7 +96,7 @@ function AlertDialogMedia({ className, ...props }: React.ComponentProps<'div'>)
86
96
  <div
87
97
  data-slot="alert-dialog-media"
88
98
  className={cn(
89
- "mb-2 inline-flex size-16 items-center justify-center rounded-full bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8",
99
+ "mb-2 inline-flex size-16 items-center justify-center rounded-sm bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8",
90
100
  className
91
101
  )}
92
102
  {...props}
@@ -166,6 +176,7 @@ export {
166
176
  AlertDialog,
167
177
  AlertDialogAction,
168
178
  AlertDialogCancel,
179
+ AlertDialogBody,
169
180
  AlertDialogContent,
170
181
  AlertDialogDescription,
171
182
  AlertDialogFooter,
@@ -3,7 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority'
3
3
  import type * as React from 'react'
4
4
 
5
5
  const alertVariants = cva(
6
- "group/alert relative grid w-full gap-0.5 rounded-lg border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-foreground *:[svg:not([class*='size-'])]:size-4",
6
+ "group/alert relative grid w-full gap-0.5 rounded-sm border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-foreground *:[svg:not([class*='size-'])]:size-4",
7
7
  {
8
8
  variants: {
9
9
  variant: {