betterstart-cli 0.0.109 → 0.0.111

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 (65) hide show
  1. package/dist/assets/adapters/next/templates/init/components/layouts/{admin-sidebar-branding-rsc.tsx → admin-sidebar-branding.tsx} +1 -1
  2. package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar.tsx +2 -2
  3. package/dist/assets/adapters/next/templates/init/components/layouts/role-gate.tsx +14 -0
  4. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode-integrate.tsx +2 -2
  5. package/dist/assets/adapters/next/templates/init/components/shared/entity-filters-bar.tsx +1 -1
  6. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-versions-drawer.tsx +1 -1
  7. package/dist/assets/adapters/next/templates/init/components/shared/media/media-filters-bar.tsx +2 -2
  8. package/dist/assets/adapters/next/templates/init/components/shared/media/media-gallery-dialog.tsx +1 -1
  9. package/dist/assets/adapters/next/templates/init/components/shared/media/media-preview.tsx +1 -1
  10. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-color-highlight.ts +1 -3
  11. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-media-insertion.ts +1 -3
  12. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor.ts +2 -6
  13. package/dist/assets/adapters/next/templates/init/pages/account-layout.tsx +2 -2
  14. package/dist/assets/adapters/next/templates/init/pages/{account-shell-rsc.tsx → account-shell.tsx} +2 -2
  15. package/dist/assets/adapters/next/templates/init/pages/{auth-gate-rsc.tsx → auth-gate.tsx} +2 -2
  16. package/dist/assets/adapters/next/templates/init/pages/authenticated-layout.tsx +2 -2
  17. package/dist/assets/adapters/next/templates/init/pages/forgot-password-form.tsx +4 -4
  18. package/dist/assets/adapters/next/templates/init/pages/forgot-password-page-skeleton.tsx +3 -3
  19. package/dist/assets/adapters/next/templates/init/pages/forgot-password-page.tsx +2 -2
  20. package/dist/assets/adapters/next/templates/init/pages/login-form.tsx +4 -4
  21. package/dist/assets/adapters/next/templates/init/pages/{login-page-rsc.tsx → login-page-content.tsx} +1 -1
  22. package/dist/assets/adapters/next/templates/init/pages/login-page-skeleton.tsx +3 -3
  23. package/dist/assets/adapters/next/templates/init/pages/login-page.tsx +4 -4
  24. package/dist/assets/adapters/next/templates/init/pages/media/media-page-content.tsx +1 -1
  25. package/dist/assets/adapters/next/templates/init/pages/profile/profile-page-content.tsx +31 -0
  26. package/dist/assets/adapters/next/templates/init/pages/profile/profile-page-skeleton.tsx +9 -0
  27. package/dist/assets/adapters/next/templates/init/pages/profile/profile-page.tsx +7 -27
  28. package/dist/assets/adapters/next/templates/init/pages/reset-password-form.tsx +8 -8
  29. package/dist/assets/adapters/next/templates/init/pages/reset-password-page-skeleton.tsx +3 -3
  30. package/dist/assets/adapters/next/templates/init/pages/reset-password-page.tsx +2 -2
  31. package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-detail-drawer.tsx +1 -1
  32. package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-page.tsx +6 -5
  33. package/dist/assets/adapters/next/templates/init/pages/settings/forms/form-notifications-drawer.tsx +1 -1
  34. package/dist/assets/adapters/next/templates/init/pages/settings/forms/forms-settings-page.tsx +6 -5
  35. package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/delete-webhook-dialog.tsx +1 -1
  36. package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhook-endpoint-dialog.tsx +1 -1
  37. package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-logs-page.tsx +6 -5
  38. package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-page.tsx +6 -5
  39. package/dist/assets/adapters/next/templates/init/pages/users/change-password-dialog.tsx +1 -1
  40. package/dist/assets/adapters/next/templates/init/pages/users/create-user-dialog.tsx +1 -1
  41. package/dist/assets/adapters/next/templates/init/pages/users/edit-role-dialog.tsx +1 -1
  42. package/dist/assets/shared-assets/react-admin/custom/content-editor/index.tsx +5 -30
  43. package/dist/assets/shared-assets/react-admin/custom/content-editor/main-toolbar-content.tsx +6 -28
  44. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/removable-image-node/removable-image-node.tsx +1 -1
  45. package/dist/assets/shared-assets/react-admin/custom/gallery-field.tsx +3 -3
  46. package/dist/assets/shared-assets/react-admin/ui/alert-dialog.tsx +6 -6
  47. package/dist/assets/shared-assets/react-admin/ui/alert.tsx +1 -1
  48. package/dist/assets/shared-assets/react-admin/ui/breadcrumb.tsx +1 -1
  49. package/dist/assets/shared-assets/react-admin/ui/calendar.tsx +1 -1
  50. package/dist/assets/shared-assets/react-admin/ui/card.tsx +1 -1
  51. package/dist/assets/shared-assets/react-admin/ui/dialog.tsx +2 -2
  52. package/dist/assets/shared-assets/react-admin/ui/drawer.tsx +2 -2
  53. package/dist/assets/shared-assets/react-admin/ui/field.tsx +2 -4
  54. package/dist/assets/shared-assets/react-admin/ui/input.tsx +1 -1
  55. package/dist/assets/shared-assets/react-admin/ui/pagination.tsx +2 -2
  56. package/dist/assets/shared-assets/react-admin/ui/sheet.tsx +1 -1
  57. package/dist/assets/shared-assets/react-admin/ui/sidebar.tsx +13 -63
  58. package/dist/assets/shared-assets/react-admin/ui/textarea.tsx +1 -1
  59. package/dist/cli.js +115 -90
  60. package/dist/cli.js.map +1 -1
  61. package/package.json +1 -1
  62. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-mobile-toolbar.ts +0 -17
  63. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-is-breakpoint.ts +0 -24
  64. package/dist/assets/adapters/next/templates/init/hooks/use-mobile.ts +0 -19
  65. package/dist/assets/shared-assets/react-admin/custom/content-editor/mobile-toolbar-content.tsx +0 -56
@@ -1,7 +1,7 @@
1
1
  import { getSetting } from '@admin/actions/settings'
2
2
  import { SidebarBranding } from './sidebar-branding'
3
3
 
4
- export async function SidebarBrandingRsc() {
4
+ export async function AdminSidebarBranding() {
5
5
  const settings = await getSetting()
6
6
 
7
7
  return <SidebarBranding initialData={settings} />
@@ -14,7 +14,7 @@ import { adminNavigation } from '@admin/data/navigation'
14
14
  import { groupAdminNavigationItems } from '@admin/utils/navigation/sidebar'
15
15
  import { Settings, Users } from 'lucide-react'
16
16
  import { Fragment, Suspense } from 'react'
17
- import { SidebarBrandingRsc } from './admin-sidebar-branding-rsc'
17
+ import { AdminSidebarBranding } from './admin-sidebar-branding'
18
18
  import { BrandingSkeleton } from './admin-sidebar-branding-skeleton'
19
19
  import { SidebarNavLink } from './admin-sidebar-nav-link'
20
20
  import { SidebarUserMenu } from './admin-sidebar-user-menu'
@@ -27,7 +27,7 @@ export function AdminSidebar(props: ComponentProps<typeof Sidebar>) {
27
27
  <Sidebar collapsible="icon" {...props}>
28
28
  <SidebarHeader className="flex h-14 w-full items-center border-t border-b border-border/80">
29
29
  <Suspense fallback={<BrandingSkeleton />}>
30
- <SidebarBrandingRsc />
30
+ <AdminSidebarBranding />
31
31
  </Suspense>
32
32
  </SidebarHeader>
33
33
  <SidebarContent className="pt-4 pb-1">
@@ -0,0 +1,14 @@
1
+ import type { UserRole } from '@admin/types/auth'
2
+ import { requireRole } from '@admin/auth/middleware'
3
+
4
+ export async function RoleGate({
5
+ roles,
6
+ children
7
+ }: {
8
+ roles: readonly UserRole[]
9
+ children: React.ReactNode
10
+ }) {
11
+ await requireRole(roles)
12
+
13
+ return <>{children}</>
14
+ }
@@ -49,9 +49,9 @@ export function DevModeIntegrateButton({
49
49
  <Drawer swipeDirection="right" onOpenChange={handleOpenChange}>
50
50
  <DrawerTrigger render={<Button type="button" variant="outline" />}>
51
51
  <Code2 />
52
- <span className="hidden sm:inline">Dev Mode</span>
52
+ <span className="inline">Dev Mode</span>
53
53
  </DrawerTrigger>
54
- <DrawerContent className="w-full overflow-hidden data-[swipe-direction=right]:sm:max-w-2xl data-[swipe-direction=right]:lg:max-w-4xl">
54
+ <DrawerContent className="w-full overflow-hidden data-[swipe-direction=right]:max-w-4xl">
55
55
  <DrawerHeader className="pb-4">
56
56
  <DrawerTitle>{integration.schemaLabel}</DrawerTitle>
57
57
  <DrawerDescription>
@@ -64,7 +64,7 @@ export function EntityFiltersBar({
64
64
  return (
65
65
  <div
66
66
  className={cn(
67
- 'sticky top-14 z-10 flex h-16 gap-1 overflow-x-clip bg-background px-4 transition-shadow xl:flex-row xl:items-center xl:justify-between',
67
+ 'sticky top-14 z-10 flex h-16 flex-row items-center justify-between gap-1 overflow-x-clip bg-background px-4 transition-shadow',
68
68
  {
69
69
  'shadow-modal/3': hasScrolled
70
70
  }
@@ -43,7 +43,7 @@ export function EntityVersionsDrawer({
43
43
  }: EntityVersionsDrawerProps) {
44
44
  return (
45
45
  <Drawer swipeDirection="right" open={open} onOpenChange={onOpenChange} modal>
46
- <DrawerContent className="h-full sm:max-w-lg">
46
+ <DrawerContent className="h-full max-w-lg">
47
47
  <DrawerHeader>
48
48
  <DrawerTitle>Versions</DrawerTitle>
49
49
  <DrawerDescription>
@@ -48,7 +48,7 @@ export function MediaFiltersBar({
48
48
  return (
49
49
  <div
50
50
  className={cn(
51
- 'sticky top-14 z-9 flex h-16 flex-col gap-1 overflow-clip bg-background px-4 transition-shadow xl:flex-row xl:items-center xl:justify-between',
51
+ 'sticky top-14 z-9 flex h-16 flex-row items-center justify-between gap-1 overflow-clip bg-background px-4 transition-shadow',
52
52
  {
53
53
  'shadow-modal/3': hasScrolled
54
54
  }
@@ -81,7 +81,7 @@ export function MediaFiltersBar({
81
81
  </ButtonGroup>
82
82
  </div>
83
83
 
84
- <div className="flex items-center gap-1 self-end xl:self-auto">
84
+ <div className="flex items-center gap-1 self-auto">
85
85
  {actions}
86
86
 
87
87
  {selection.isSelectMode ? (
@@ -99,7 +99,7 @@ export function MediaGalleryDialog({
99
99
  onOpenChange(next)
100
100
  }}
101
101
  >
102
- <DialogContent className="flex h-[80svh] max-h-[700px] min-h-0 flex-col gap-0 overflow-hidden sm:max-w-3xl">
102
+ <DialogContent className="flex h-[80svh] max-h-[700px] min-h-0 max-w-3xl flex-col gap-0 overflow-hidden">
103
103
  <DialogHeader>
104
104
  <DialogTitle>Select file</DialogTitle>
105
105
  <DialogDescription>
@@ -26,7 +26,7 @@ export function MediaPreview({ media, isFilled = false, showMetadata = false }:
26
26
  'object-contain': !isFilled
27
27
  })}
28
28
  fill
29
- sizes="(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 200px"
29
+ sizes="200px"
30
30
  unoptimized
31
31
  loading="lazy"
32
32
  decoding="async"
@@ -2,7 +2,6 @@
2
2
 
3
3
  import type { ContentEditorHighlightColorOption } from '@admin/utils/editor/content-editor-highlight-color-option'
4
4
  import type { Editor } from '@tiptap/react'
5
- import { useIsBreakpoint } from '@admin/hooks/content-editor/use-is-breakpoint'
6
5
  import { useTiptapEditor } from '@admin/hooks/content-editor/use-tiptap-editor'
7
6
  import { CONTENT_EDITOR_HIGHLIGHT_COLOR_OPTIONS } from '@admin/utils/editor/content-editor-highlight-color-options'
8
7
  import { CONTENT_EDITOR_HIGHLIGHT_COLORS } from '@admin/utils/editor/content-editor-highlight-colors'
@@ -152,7 +151,6 @@ export function useColorHighlight(config: UseColorHighlightConfig) {
152
151
  } = config
153
152
 
154
153
  const { editor } = useTiptapEditor(providedEditor)
155
- const isMobile = useIsBreakpoint()
156
154
  const [isVisible, setIsVisible] = useState<boolean>(true)
157
155
  const canColorHighlightState = canColorHighlight(editor, mode)
158
156
  const actualColor = highlightColor
@@ -222,7 +220,7 @@ export function useColorHighlight(config: UseColorHighlightConfig) {
222
220
  },
223
221
  {
224
222
  enabled: isVisible && canColorHighlightState,
225
- enableOnContentEditable: !isMobile,
223
+ enableOnContentEditable: true,
226
224
  enableOnFormTags: true
227
225
  }
228
226
  )
@@ -2,7 +2,6 @@
2
2
 
3
3
  import * as React from 'react'
4
4
  import type { Editor } from '@tiptap/react'
5
- import { useIsBreakpoint } from '@admin/hooks/content-editor/use-is-breakpoint'
6
5
  import { useTiptapEditor } from '@admin/hooks/content-editor/use-tiptap-editor'
7
6
  import { canInsertContentEditorMediaPlaceholder } from '@admin/utils/editor/can-insert-content-editor-media-placeholder'
8
7
  import { CONTENT_EDITOR_MEDIA_SHORTCUT_KEY } from '@admin/utils/editor/content-editor-media-shortcut-key'
@@ -20,7 +19,6 @@ export function useContentEditorMediaInsertion({
20
19
  onInserted
21
20
  }: UseContentEditorMediaInsertionOptions = {}) {
22
21
  const { editor } = useTiptapEditor(providedEditor)
23
- const isMobile = useIsBreakpoint()
24
22
  const canInsert = canInsertContentEditorMediaPlaceholder(editor)
25
23
  const isActive = isContentEditorMediaPlaceholderActive(editor)
26
24
  const isVisible = Boolean(editor?.isEditable)
@@ -41,7 +39,7 @@ export function useContentEditorMediaInsertion({
41
39
  },
42
40
  {
43
41
  enabled: isVisible && canInsert,
44
- enableOnContentEditable: !isMobile,
42
+ enableOnContentEditable: true,
45
43
  enableOnFormTags: true
46
44
  }
47
45
  )
@@ -42,7 +42,6 @@ export interface UseContentEditorOptions {
42
42
  placeholder?: string
43
43
  disabled: boolean
44
44
  defaultMode: ContentEditorMode
45
- onModeToggle?: () => void
46
45
  }
47
46
 
48
47
  export function useContentEditor({
@@ -50,8 +49,7 @@ export function useContentEditor({
50
49
  onChange,
51
50
  placeholder,
52
51
  disabled,
53
- defaultMode,
54
- onModeToggle
52
+ defaultMode
55
53
  }: UseContentEditorOptions) {
56
54
  const [mode, setMode] = React.useState<ContentEditorMode>(defaultMode)
57
55
  const [sourceSelectionRequest, setSourceSelectionRequest] =
@@ -257,8 +255,6 @@ export function useContentEditor({
257
255
  )
258
256
 
259
257
  const handleModeChange = React.useCallback(() => {
260
- onModeToggle?.()
261
-
262
258
  if (mode === 'source') {
263
259
  pendingRichSelectionOffsetRef.current = sourceSelectionRef.current
264
260
  setMode('rich')
@@ -282,7 +278,7 @@ export function useContentEditor({
282
278
  }
283
279
 
284
280
  setMode('source')
285
- }, [editor, mode, onModeToggle])
281
+ }, [editor, mode])
286
282
 
287
283
  return {
288
284
  activeSlashIndex,
@@ -1,11 +1,11 @@
1
1
  import { ContentSkeleton } from '@admin/components/layouts/content-skeleton'
2
2
  import { Suspense } from 'react'
3
- import { AccountShellRsc } from './account-shell-rsc'
3
+ import { AccountShell } from './account-shell'
4
4
 
5
5
  export default function AccountLayout({ children }: { children: React.ReactNode }) {
6
6
  return (
7
7
  <Suspense fallback={<ContentSkeleton />}>
8
- <AccountShellRsc>{children}</AccountShellRsc>
8
+ <AccountShell>{children}</AccountShell>
9
9
  </Suspense>
10
10
  )
11
11
  }
@@ -6,7 +6,7 @@ import { canAccessAdmin } from '@admin/utils/auth/can-access-admin'
6
6
  import { redirect } from 'next/navigation'
7
7
  import { MinimalAccountShell } from './minimal-account-shell'
8
8
 
9
- export async function AccountShellRsc({ children }: { children: React.ReactNode }) {
9
+ export async function AccountShell({ children }: { children: React.ReactNode }) {
10
10
  const session = await getSession({ disableCookieCache: true })
11
11
 
12
12
  if (!session?.user) {
@@ -22,7 +22,7 @@ export async function AccountShellRsc({ children }: { children: React.ReactNode
22
22
  return (
23
23
  <SidebarProvider className="min-h-svh">
24
24
  <AdminSidebar />
25
- <div className="relative flex min-w-0 flex-1 flex-col [--admin-shell-content-left:0px] md:[--admin-shell-content-left:var(--sidebar-width)] md:peer-data-[state=collapsed]:[--admin-shell-content-left:var(--sidebar-width-icon)]">
25
+ <div className="relative flex min-w-0 flex-1 flex-col [--admin-shell-content-left:var(--sidebar-width)] peer-data-[state=collapsed]:[--admin-shell-content-left:var(--sidebar-width-icon)]">
26
26
  {children}
27
27
  </div>
28
28
  </SidebarProvider>
@@ -2,13 +2,13 @@ import { requireRole, UserRole } from '@admin/auth/middleware'
2
2
  import { AdminSidebar } from '@admin/components/layouts/admin-sidebar'
3
3
  import { SidebarProvider } from '@admin/components/ui/sidebar'
4
4
 
5
- export async function AuthGateRsc({ children }: { children: React.ReactNode }) {
5
+ export async function AuthGate({ children }: { children: React.ReactNode }) {
6
6
  await requireRole([UserRole.ADMIN, UserRole.EDITOR])
7
7
 
8
8
  return (
9
9
  <SidebarProvider className="min-h-svh">
10
10
  <AdminSidebar />
11
- <div className="relative flex min-w-0 flex-1 flex-col pb-14 [--admin-shell-content-left:0px] md:[--admin-shell-content-left:var(--sidebar-width)] md:peer-data-[state=collapsed]:[--admin-shell-content-left:var(--sidebar-width-icon)]">
11
+ <div className="relative flex min-w-0 flex-1 flex-col pb-14 [--admin-shell-content-left:var(--sidebar-width)] peer-data-[state=collapsed]:[--admin-shell-content-left:var(--sidebar-width-icon)]">
12
12
  {children}
13
13
  </div>
14
14
  </SidebarProvider>
@@ -1,11 +1,11 @@
1
1
  import { ContentSkeleton } from '@admin/components/layouts/content-skeleton'
2
2
  import { Suspense } from 'react'
3
- import { AuthGateRsc } from './auth-gate-rsc'
3
+ import { AuthGate } from './auth-gate'
4
4
 
5
5
  export default function AdminAuthLayout({ children }: { children: React.ReactNode }) {
6
6
  return (
7
7
  <Suspense fallback={<ContentSkeleton />}>
8
- <AuthGateRsc>{children}</AuthGateRsc>
8
+ <AuthGate>{children}</AuthGate>
9
9
  </Suspense>
10
10
  )
11
11
  }
@@ -66,17 +66,17 @@ export function ForgotPasswordForm({ className, ...props }: React.ComponentProps
66
66
  return (
67
67
  <div className={cn('flex flex-col gap-6', className)} {...props}>
68
68
  <Card className="overflow-hidden p-0">
69
- <CardContent className="grid p-0 md:grid-cols-[5fr_7fr]">
70
- <div className="relative hidden bg-muted md:block">
69
+ <CardContent className="grid grid-cols-[5fr_7fr] p-0">
70
+ <div className="relative block bg-muted">
71
71
  <Image
72
72
  src="https://assets.betterstart.dev/assets/placeholder.png"
73
73
  alt=""
74
74
  fill
75
- sizes="(min-width: 768px) 42vw, 0px"
75
+ sizes="42vw"
76
76
  className="object-cover"
77
77
  />
78
78
  </div>
79
- <div className="p-6 md:p-20">
79
+ <div className="p-20">
80
80
  <Form {...form}>
81
81
  <form
82
82
  autoComplete="off"
@@ -1,9 +1,9 @@
1
1
  export function ForgotPasswordPageSkeleton() {
2
2
  return (
3
3
  <div className="overflow-hidden rounded-sm border bg-card">
4
- <div className="grid md:grid-cols-[5fr_7fr]">
5
- <div className="hidden min-h-[460px] bg-muted md:block" />
6
- <div className="flex min-h-[460px] flex-col gap-10 p-6 md:p-20">
4
+ <div className="grid grid-cols-[5fr_7fr]">
5
+ <div className="block min-h-[460px] bg-muted" />
6
+ <div className="flex min-h-[460px] flex-col gap-10 p-20">
7
7
  <div className="space-y-3">
8
8
  <div className="h-6 w-40 animate-pulse rounded-md bg-muted" />
9
9
  <div className="h-4 w-full max-w-72 animate-pulse rounded-md bg-muted" />
@@ -10,8 +10,8 @@ export const metadata: Metadata = {
10
10
 
11
11
  export default function ForgotPasswordPage() {
12
12
  return (
13
- <div className="flex min-h-svh flex-col items-center justify-center bg-background p-6 md:p-10">
14
- <div className="w-full max-w-sm md:max-w-4xl">
13
+ <div className="flex min-h-svh flex-col items-center justify-center bg-background p-10">
14
+ <div className="w-full max-w-4xl">
15
15
  <Suspense fallback={<ForgotPasswordPageSkeleton />}>
16
16
  <ForgotPasswordForm />
17
17
  </Suspense>
@@ -81,13 +81,13 @@ export function LoginForm({ className, ...props }: React.ComponentProps<'div'>)
81
81
  return (
82
82
  <div className={cn('flex flex-col gap-6', className)} {...props}>
83
83
  <Card className="overflow-hidden p-0">
84
- <CardContent className="grid p-0 md:grid-cols-[5fr_7fr]">
85
- <div className="relative hidden bg-muted md:block">
84
+ <CardContent className="grid grid-cols-[5fr_7fr] p-0">
85
+ <div className="relative block bg-muted">
86
86
  <Image
87
87
  src="https://assets.betterstart.dev/assets/placeholder.png"
88
88
  alt=""
89
89
  fill
90
- sizes="(min-width: 768px) 42vw, 0px"
90
+ sizes="42vw"
91
91
  className="object-cover"
92
92
  />
93
93
  </div>
@@ -96,7 +96,7 @@ export function LoginForm({ className, ...props }: React.ComponentProps<'div'>)
96
96
  autoComplete="off"
97
97
  noValidate
98
98
  onSubmit={form.handleSubmit(handleSubmit, handleInvalid)}
99
- className="p-6 md:p-20"
99
+ className="p-20"
100
100
  >
101
101
  <FieldGroup className="gap-10 pb-12">
102
102
  <div className="flex flex-col items-start">
@@ -3,7 +3,7 @@ import { getAdminPostLoginPath } from '@admin/utils/auth/get-admin-post-login-pa
3
3
  import { redirect } from 'next/navigation'
4
4
  import { LoginForm } from './login-form'
5
5
 
6
- export async function LoginPageRsc() {
6
+ export async function LoginPageContent() {
7
7
  const session = await getSession({ disableCookieCache: true })
8
8
 
9
9
  if (session?.user) {
@@ -1,9 +1,9 @@
1
1
  export function LoginPageSkeleton() {
2
2
  return (
3
3
  <div className="overflow-hidden rounded-sm border bg-card">
4
- <div className="grid md:grid-cols-[5fr_7fr]">
5
- <div className="hidden min-h-[540px] bg-muted md:block" />
6
- <div className="flex min-h-[540px] flex-col gap-10 p-6 md:p-20">
4
+ <div className="grid grid-cols-[5fr_7fr]">
5
+ <div className="block min-h-[540px] bg-muted" />
6
+ <div className="flex min-h-[540px] flex-col gap-10 p-20">
7
7
  <div className="space-y-3">
8
8
  <div className="h-6 w-32 animate-pulse rounded-md bg-muted" />
9
9
  <div className="h-4 w-40 animate-pulse rounded-md bg-muted" />
@@ -1,6 +1,6 @@
1
1
  import type { Metadata } from 'next'
2
2
  import { Suspense } from 'react'
3
- import { LoginPageRsc } from './login-page-rsc'
3
+ import { LoginPageContent } from './login-page-content'
4
4
  import { LoginPageSkeleton } from './login-page-skeleton'
5
5
 
6
6
  export const metadata: Metadata = {
@@ -10,10 +10,10 @@ export const metadata: Metadata = {
10
10
 
11
11
  export default function LoginPage() {
12
12
  return (
13
- <div className="flex min-h-svh flex-col items-center justify-center bg-background p-6 md:p-10">
14
- <div className="w-full max-w-sm md:max-w-4xl">
13
+ <div className="flex min-h-svh flex-col items-center justify-center bg-background p-10">
14
+ <div className="w-full max-w-4xl">
15
15
  <Suspense fallback={<LoginPageSkeleton />}>
16
- <LoginPageRsc />
16
+ <LoginPageContent />
17
17
  </Suspense>
18
18
  </div>
19
19
  </div>
@@ -238,7 +238,7 @@ export function MediaPageContent() {
238
238
  selectedIds={selected}
239
239
  isSelectMode={isSelectMode}
240
240
  onItemClick={handleItemClick}
241
- className="px-px pt-px pb-12 lg:grid-cols-12"
241
+ className="grid-cols-12 px-px pt-px pb-12"
242
242
  />
243
243
  {total > DEFAULT_MEDIA_PAGE_SIZE ? (
244
244
  <MediaGridPagination
@@ -0,0 +1,31 @@
1
+ import { getSession } from '@admin/auth/middleware'
2
+ import { PageHeader } from '@admin/components/shared/page-header'
3
+ import { UserRole } from '@admin/types/auth'
4
+ import { redirect } from 'next/navigation'
5
+ import { ProfileForm } from './profile-form'
6
+
7
+ export async function ProfilePageContent() {
8
+ const session = await getSession()
9
+
10
+ if (!session?.user) {
11
+ redirect('/admin/login')
12
+ }
13
+
14
+ const showPageHeader =
15
+ session.user.role === UserRole.ADMIN || session.user.role === UserRole.EDITOR
16
+
17
+ return (
18
+ <>
19
+ {showPageHeader && <PageHeader title="Profile" />}
20
+ <main className="container mx-auto w-full max-w-5xl p-4">
21
+ <ProfileForm
22
+ user={{
23
+ name: session.user.name,
24
+ email: session.user.email,
25
+ image: session.user.image ?? null
26
+ }}
27
+ />
28
+ </main>
29
+ </>
30
+ )
31
+ }
@@ -0,0 +1,9 @@
1
+ export function ProfilePageSkeleton() {
2
+ return (
3
+ <main className="container mx-auto w-full max-w-5xl p-4">
4
+ <div className="flex h-48 items-center justify-center">
5
+ <div className="text-muted-foreground">Loading Profile…</div>
6
+ </div>
7
+ </main>
8
+ )
9
+ }
@@ -1,31 +1,11 @@
1
- import { getSession } from '@admin/auth/middleware'
2
- import { PageHeader } from '@admin/components/shared/page-header'
3
- import { UserRole } from '@admin/types/auth'
4
- import { redirect } from 'next/navigation'
5
- import { ProfileForm } from './profile-form'
6
-
7
- export default async function ProfilePage() {
8
- const session = await getSession()
9
-
10
- if (!session?.user) {
11
- redirect('/admin/login')
12
- }
13
-
14
- const showPageHeader =
15
- session.user.role === UserRole.ADMIN || session.user.role === UserRole.EDITOR
1
+ import * as React from 'react'
2
+ import { ProfilePageContent } from './profile-page-content'
3
+ import { ProfilePageSkeleton } from './profile-page-skeleton'
16
4
 
5
+ export default function ProfilePage() {
17
6
  return (
18
- <>
19
- {showPageHeader && <PageHeader title="Profile" />}
20
- <main className="container mx-auto w-full max-w-5xl p-4">
21
- <ProfileForm
22
- user={{
23
- name: session.user.name,
24
- email: session.user.email,
25
- image: session.user.image ?? null
26
- }}
27
- />
28
- </main>
29
- </>
7
+ <React.Suspense fallback={<ProfilePageSkeleton />}>
8
+ <ProfilePageContent />
9
+ </React.Suspense>
30
10
  )
31
11
  }
@@ -53,17 +53,17 @@ export function ResetPasswordForm({ className, ...props }: React.ComponentProps<
53
53
  return (
54
54
  <div className={cn('flex flex-col gap-6', className)} {...props}>
55
55
  <Card className="overflow-hidden p-0">
56
- <CardContent className="grid p-0 md:grid-cols-[5fr_7fr]">
57
- <div className="relative hidden bg-muted md:block">
56
+ <CardContent className="grid grid-cols-[5fr_7fr] p-0">
57
+ <div className="relative block bg-muted">
58
58
  <Image
59
59
  src="https://assets.betterstart.dev/assets/placeholder.png"
60
60
  alt=""
61
61
  fill
62
- sizes="(min-width: 768px) 42vw, 0px"
62
+ sizes="42vw"
63
63
  className="object-cover"
64
64
  />
65
65
  </div>
66
- <div className="p-6 md:p-20">
66
+ <div className="p-20">
67
67
  <FieldGroup className="gap-10 pb-12">
68
68
  <div className="flex flex-col items-start">
69
69
  <h1 className="text-xl font-medium">Invalid reset link</h1>
@@ -112,13 +112,13 @@ export function ResetPasswordForm({ className, ...props }: React.ComponentProps<
112
112
  return (
113
113
  <div className={cn('flex flex-col gap-6', className)} {...props}>
114
114
  <Card className="overflow-hidden p-0">
115
- <CardContent className="grid p-0 md:grid-cols-[5fr_7fr]">
116
- <div className="relative hidden bg-muted md:block">
115
+ <CardContent className="grid grid-cols-[5fr_7fr] p-0">
116
+ <div className="relative block bg-muted">
117
117
  <Image
118
118
  src="https://assets.betterstart.dev/assets/placeholder.png"
119
119
  alt=""
120
120
  fill
121
- sizes="(min-width: 768px) 42vw, 0px"
121
+ sizes="42vw"
122
122
  className="object-cover"
123
123
  />
124
124
  </div>
@@ -127,7 +127,7 @@ export function ResetPasswordForm({ className, ...props }: React.ComponentProps<
127
127
  autoComplete="off"
128
128
  noValidate
129
129
  onSubmit={form.handleSubmit(handleSubmit, handleInvalid)}
130
- className="p-6 md:p-20"
130
+ className="p-20"
131
131
  >
132
132
  <FieldGroup className="gap-10 pb-12">
133
133
  <div className="flex flex-col items-start">
@@ -1,9 +1,9 @@
1
1
  export function ResetPasswordPageSkeleton() {
2
2
  return (
3
3
  <div className="overflow-hidden rounded-sm border bg-card">
4
- <div className="grid md:grid-cols-[5fr_7fr]">
5
- <div className="hidden min-h-[520px] bg-muted md:block" />
6
- <div className="flex min-h-[520px] flex-col gap-10 p-6 md:p-20">
4
+ <div className="grid grid-cols-[5fr_7fr]">
5
+ <div className="block min-h-[520px] bg-muted" />
6
+ <div className="flex min-h-[520px] flex-col gap-10 p-20">
7
7
  <div className="space-y-3">
8
8
  <div className="h-6 w-36 animate-pulse rounded-md bg-muted" />
9
9
  <div className="h-4 w-56 animate-pulse rounded-md bg-muted" />
@@ -10,8 +10,8 @@ export const metadata: Metadata = {
10
10
 
11
11
  export default function ResetPasswordPage() {
12
12
  return (
13
- <div className="flex min-h-svh flex-col items-center justify-center bg-background p-6 md:p-10">
14
- <div className="w-full max-w-sm md:max-w-4xl">
13
+ <div className="flex min-h-svh flex-col items-center justify-center bg-background p-10">
14
+ <div className="w-full max-w-4xl">
15
15
  <Suspense fallback={<ResetPasswordPageSkeleton />}>
16
16
  <ResetPasswordForm />
17
17
  </Suspense>
@@ -37,7 +37,7 @@ function formatMetadata(metadata: Record<string, unknown> | null): string {
37
37
  export function AuditLogDetailDrawer({ auditLog, open, onOpenChange }: AuditLogDetailDrawerProps) {
38
38
  return (
39
39
  <Drawer swipeDirection="right" open={open} onOpenChange={onOpenChange} modal>
40
- <DrawerContent className="h-full sm:max-w-xl">
40
+ <DrawerContent className="h-full max-w-xl">
41
41
  <DrawerHeader>
42
42
  <DrawerTitle>Audit Event</DrawerTitle>
43
43
  <DrawerDescription>
@@ -1,14 +1,15 @@
1
1
  import * as React from 'react'
2
- import { requireRole, UserRole } from '@admin/auth/middleware'
2
+ import { RoleGate } from '@admin/components/layouts/role-gate'
3
+ import { UserRole } from '@admin/types/auth'
3
4
  import { AuditLogPageContent } from './audit-log-page-content'
4
5
  import { AuditLogPageSkeleton } from './audit-log-page-skeleton'
5
6
 
6
- export default async function AuditLogPage() {
7
- await requireRole([UserRole.ADMIN])
8
-
7
+ export default function AuditLogPage() {
9
8
  return (
10
9
  <React.Suspense fallback={<AuditLogPageSkeleton />}>
11
- <AuditLogPageContent />
10
+ <RoleGate roles={[UserRole.ADMIN]}>
11
+ <AuditLogPageContent />
12
+ </RoleGate>
12
13
  </React.Suspense>
13
14
  )
14
15
  }
@@ -83,7 +83,7 @@ export function FormNotificationsDrawer({
83
83
 
84
84
  return (
85
85
  <Drawer swipeDirection="right" open={open} onOpenChange={onOpenChange} modal>
86
- <DrawerContent className="h-full sm:max-w-xl">
86
+ <DrawerContent className="h-full max-w-xl">
87
87
  <Form {...form}>
88
88
  <form
89
89
  autoComplete="off"
@@ -1,14 +1,15 @@
1
1
  import * as React from 'react'
2
- import { requireRole, UserRole } from '@admin/auth/middleware'
2
+ import { RoleGate } from '@admin/components/layouts/role-gate'
3
+ import { UserRole } from '@admin/types/auth'
3
4
  import { FormsSettingsPageContent } from './forms-settings-page-content'
4
5
  import { FormsSettingsPageSkeleton } from './forms-settings-page-skeleton'
5
6
 
6
- export default async function FormsSettingsPage() {
7
- await requireRole([UserRole.ADMIN, UserRole.EDITOR])
8
-
7
+ export default function FormsSettingsPage() {
9
8
  return (
10
9
  <React.Suspense fallback={<FormsSettingsPageSkeleton />}>
11
- <FormsSettingsPageContent />
10
+ <RoleGate roles={[UserRole.ADMIN, UserRole.EDITOR]}>
11
+ <FormsSettingsPageContent />
12
+ </RoleGate>
12
13
  </React.Suspense>
13
14
  )
14
15
  }