create-nextjs-cms 0.9.28 → 0.9.30

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 (142) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +71 -71
  3. package/dist/helpers/utils.js +16 -16
  4. package/dist/lib/section-creators.js +166 -166
  5. package/package.json +2 -2
  6. package/templates/default/.eslintrc.json +5 -5
  7. package/templates/default/.prettierignore +7 -7
  8. package/templates/default/.prettierrc.json +27 -27
  9. package/templates/default/CHANGELOG.md +140 -140
  10. package/templates/default/_gitignore +57 -57
  11. package/templates/default/app/(auth)/auth/login/LoginPage.tsx +192 -192
  12. package/templates/default/app/(auth)/auth/login/page.tsx +11 -11
  13. package/templates/default/app/(auth)/auth-language-provider.tsx +34 -34
  14. package/templates/default/app/(auth)/layout.tsx +81 -81
  15. package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
  16. package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
  17. package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
  18. package/templates/default/app/(rootLayout)/dashboard/page.tsx +70 -70
  19. package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +20 -20
  20. package/templates/default/app/(rootLayout)/layout.tsx +81 -81
  21. package/templates/default/app/(rootLayout)/loading.tsx +10 -10
  22. package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
  23. package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
  24. package/templates/default/app/(rootLayout)/section/[section]/page.tsx +19 -19
  25. package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
  26. package/templates/default/app/api/auth/csrf/route.ts +25 -25
  27. package/templates/default/app/api/auth/refresh/route.ts +10 -10
  28. package/templates/default/app/api/auth/route.ts +49 -49
  29. package/templates/default/app/api/auth/session/route.ts +20 -20
  30. package/templates/default/app/api/document/route.ts +165 -165
  31. package/templates/default/app/api/editor/photo/route.ts +49 -49
  32. package/templates/default/app/api/photo/route.ts +27 -27
  33. package/templates/default/app/api/submit/section/item/[slug]/route.ts +95 -95
  34. package/templates/default/app/api/submit/section/item/route.ts +56 -56
  35. package/templates/default/app/api/submit/section/simple/route.ts +86 -86
  36. package/templates/default/app/api/video/route.ts +174 -174
  37. package/templates/default/app/globals.css +236 -236
  38. package/templates/default/cms.config.ts +56 -56
  39. package/templates/default/components/admin/admin-card.tsx +165 -165
  40. package/templates/default/components/admin/admin-edit-page.tsx +124 -124
  41. package/templates/default/components/admin/admin-privilege-card.tsx +184 -184
  42. package/templates/default/components/admin/new-admin-form.tsx +172 -172
  43. package/templates/default/components/container-box.tsx +24 -24
  44. package/templates/default/components/dnd-kit/draggable.tsx +21 -21
  45. package/templates/default/components/dnd-kit/droppable.tsx +20 -20
  46. package/templates/default/components/dnd-kit/sortable-item.tsx +18 -18
  47. package/templates/default/components/feedback/error-component.tsx +16 -16
  48. package/templates/default/components/feedback/info-card.tsx +93 -93
  49. package/templates/default/components/feedback/loading-spinners.tsx +67 -67
  50. package/templates/default/components/feedback/modal.tsx +166 -166
  51. package/templates/default/components/feedback/progress-bar.tsx +48 -48
  52. package/templates/default/components/feedback/tooltip-component.tsx +27 -27
  53. package/templates/default/components/form/form-input-element.tsx +70 -70
  54. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  55. package/templates/default/components/form/helpers/util.ts +17 -17
  56. package/templates/default/components/form/inputs/checkbox-form-input.tsx +46 -46
  57. package/templates/default/components/form/inputs/color-form-input.tsx +44 -44
  58. package/templates/default/components/form/inputs/date-form-input.tsx +93 -93
  59. package/templates/default/components/form/inputs/map-form-input.tsx +141 -141
  60. package/templates/default/components/form/inputs/multiple-select-form-input.tsx +85 -85
  61. package/templates/default/components/form/inputs/number-form-input.tsx +43 -43
  62. package/templates/default/components/form/inputs/password-form-input.tsx +47 -47
  63. package/templates/default/components/form/inputs/photo-form-input.tsx +279 -279
  64. package/templates/default/components/form/inputs/rich-text-form-input.tsx +148 -148
  65. package/templates/default/components/form/inputs/select-form-input.tsx +159 -159
  66. package/templates/default/components/form/inputs/slug-form-input.tsx +131 -131
  67. package/templates/default/components/form/inputs/tags-form-input.tsx +255 -255
  68. package/templates/default/components/form/inputs/text-form-input.tsx +61 -61
  69. package/templates/default/components/form/inputs/textarea-form-input.tsx +61 -61
  70. package/templates/default/components/layout/default-nav-items.tsx +3 -3
  71. package/templates/default/components/layout/layout.tsx +84 -84
  72. package/templates/default/components/layout/navbar.tsx +258 -258
  73. package/templates/default/components/layout/sidebar-dropdown-item.tsx +83 -83
  74. package/templates/default/components/layout/sidebar-item.tsx +24 -24
  75. package/templates/default/components/layout/sidebar.tsx +229 -229
  76. package/templates/default/components/layout/theme-provider.tsx +8 -8
  77. package/templates/default/components/layout/theme-toggle.tsx +39 -39
  78. package/templates/default/components/locale/locale-switcher.tsx +98 -98
  79. package/templates/default/components/media/dropzone.tsx +154 -154
  80. package/templates/default/components/media/protected-document.tsx +44 -44
  81. package/templates/default/components/media/protected-image.tsx +143 -143
  82. package/templates/default/components/media/protected-video.tsx +76 -76
  83. package/templates/default/components/multi-select.tsx +1150 -1150
  84. package/templates/default/components/pages/admins-page.tsx +43 -43
  85. package/templates/default/components/pages/browse-page.tsx +106 -106
  86. package/templates/default/components/pages/categorized-section-page.tsx +31 -31
  87. package/templates/default/components/pages/dashboard-page-alt.tsx +45 -45
  88. package/templates/default/components/pages/item-edit-page.tsx +267 -267
  89. package/templates/default/components/pages/log-page.tsx +107 -107
  90. package/templates/default/components/pages/new-page.tsx +183 -183
  91. package/templates/default/components/pages/section-page.tsx +203 -203
  92. package/templates/default/components/pages/settings-page.tsx +232 -232
  93. package/templates/default/components/pagination/pagination-buttons.tsx +147 -147
  94. package/templates/default/components/pagination/pagination.tsx +36 -36
  95. package/templates/default/components/sections/category-delete-confirm-page.tsx +130 -130
  96. package/templates/default/components/sections/category-section-select-input.tsx +139 -139
  97. package/templates/default/components/sections/conditional-fields.tsx +49 -49
  98. package/templates/default/components/sections/section-icon.tsx +8 -8
  99. package/templates/default/components/sections/section-item-card.tsx +143 -143
  100. package/templates/default/components/sections/section-item-status-badge.tsx +17 -17
  101. package/templates/default/components/sections/select-input-buttons.tsx +125 -125
  102. package/templates/default/components/select-box.tsx +98 -98
  103. package/templates/default/components/ui/accordion.tsx +53 -53
  104. package/templates/default/components/ui/alert-dialog.tsx +113 -113
  105. package/templates/default/components/ui/alert.tsx +47 -47
  106. package/templates/default/components/ui/badge.tsx +38 -38
  107. package/templates/default/components/ui/card.tsx +43 -43
  108. package/templates/default/components/ui/command.tsx +137 -137
  109. package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
  110. package/templates/default/components/ui/custom-dialog.tsx +123 -123
  111. package/templates/default/components/ui/dialog.tsx +123 -123
  112. package/templates/default/components/ui/direction.tsx +22 -22
  113. package/templates/default/components/ui/dropdown-menu.tsx +182 -182
  114. package/templates/default/components/ui/input-group.tsx +54 -54
  115. package/templates/default/components/ui/input.tsx +22 -22
  116. package/templates/default/components/ui/label.tsx +19 -19
  117. package/templates/default/components/ui/popover.tsx +42 -42
  118. package/templates/default/components/ui/progress.tsx +31 -31
  119. package/templates/default/components/ui/scroll-area.tsx +42 -42
  120. package/templates/default/components/ui/select.tsx +165 -165
  121. package/templates/default/components/ui/separator.tsx +28 -28
  122. package/templates/default/components/ui/sheet.tsx +103 -103
  123. package/templates/default/components/ui/spinner.tsx +16 -16
  124. package/templates/default/components/ui/switch.tsx +29 -29
  125. package/templates/default/components/ui/table.tsx +83 -83
  126. package/templates/default/components/ui/tabs.tsx +55 -55
  127. package/templates/default/components/ui/toast.tsx +113 -113
  128. package/templates/default/components/ui/toaster.tsx +35 -35
  129. package/templates/default/components/ui/tooltip.tsx +30 -30
  130. package/templates/default/components/ui/use-toast.ts +187 -187
  131. package/templates/default/drizzle.config.ts +4 -4
  132. package/templates/default/dynamic-schemas/schema.ts +75 -225
  133. package/templates/default/env/env.ts +46 -46
  134. package/templates/default/envConfig.ts +4 -4
  135. package/templates/default/lib/postinstall.js +14 -14
  136. package/templates/default/lib/utils.ts +6 -6
  137. package/templates/default/next-env.d.ts +6 -6
  138. package/templates/default/next.config.ts +24 -24
  139. package/templates/default/package.json +1 -1
  140. package/templates/default/postcss.config.mjs +6 -6
  141. package/templates/default/proxy.ts +32 -32
  142. package/templates/default/tsconfig.json +48 -48
@@ -1,173 +1,173 @@
1
- import { useI18n } from 'nextjs-cms/translations/client'
2
- import React from 'react'
3
- import { useModal } from '@/components/feedback/modal-context'
4
- import InfoCard from '@/components/feedback/info-card'
5
- import { useToast } from '@/components/ui/use-toast'
6
- import { trpc } from '@/app/_trpc/client'
7
- import AdminRoleCard from '@/components/admin/admin-privilege-card'
8
- import { Button } from '@/components/ui/button'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
+ import React from 'react'
3
+ import { useModal } from '@/components/feedback/modal-context'
4
+ import InfoCard from '@/components/feedback/info-card'
5
+ import { useToast } from '@/components/ui/use-toast'
6
+ import { trpc } from '@/app/_trpc/client'
7
+ import AdminRoleCard from '@/components/admin/admin-privilege-card'
8
+ import { Button } from '@/components/ui/button'
9
9
  import type { RouterOutputs } from '@/app/_trpc/types'
10
-
11
- export default function NewAdminForm({
12
- privileges,
13
- action,
14
- }: {
15
- privileges: RouterOutputs['admins']['list']['privileges']
16
- action: any
17
- }) {
18
- const t = useI18n()
19
- const { setModal, modal, modalResponse, setModalResponse } = useModal()
20
- const { toast } = useToast()
21
- const formRef = React.useRef<HTMLFormElement>(null)
22
- const [allChecked, setAllChecked] = React.useState<boolean | 'edited' | null>(null)
23
- const usernameRef = React.useRef<HTMLInputElement>(null)
24
- const passwordRef = React.useRef<HTMLInputElement>(null)
25
-
26
- const mutation = trpc.admins.create.useMutation({
27
- onError: (error) => {
28
- setModal({
29
- title: t('createNewAdmin'),
30
- body: (
31
- <div className='p-4'>
32
- <InfoCard result={{ key: 'danger', title: error.message, status: false }} />
33
- </div>
34
- ),
35
- headerColor: 'bg-red-700',
36
- titleColor: 'text-white',
37
- lang: 'en',
38
- })
39
- },
40
-
41
- onSuccess: (data) => {
42
- setModal(null)
43
- setModalResponse(null)
44
- setAllChecked(false)
45
- action()
46
-
47
- /**
48
- * Empty the form
49
- */
50
- if (formRef.current) {
51
- formRef.current.reset()
52
- }
53
-
54
- /**
55
- * Show a success toast
56
- */
57
- toast({
58
- variant: 'success',
59
- title: t('createNewAdmin'),
60
- description: t('itemCreatedSuccessfully'),
61
- })
62
- },
63
- })
64
-
65
- const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
66
- e.preventDefault()
67
-
68
- /**
69
- * Check username and password
70
- */
71
- if (!usernameRef.current?.value || !passwordRef.current?.value) {
72
- setModal({
73
- title: t('createNewAdmin'),
74
- body: <div className='p-4'>{t('usernamePasswordRequired')}</div>,
75
- headerColor: 'bg-red-700',
76
- titleColor: 'text-white',
77
- lang: 'en',
78
- })
79
- return
80
- }
81
-
82
- const data = new FormData(e.currentTarget)
83
- const values = Object.fromEntries(data.entries())
84
- values.form_type = 'new'
85
-
86
- // Convert the privileges to an array of objects
87
- const privileges = Object.entries(values).filter(([key]) => key.includes('privileges'))
88
- const privilegesArray = privileges.map(([key, value]) => JSON.parse(value as string))
89
-
90
- mutation.mutate({
91
- username: usernameRef.current.value,
92
- password: passwordRef.current.value,
93
- privileges: privilegesArray,
94
- })
95
- }
96
-
97
- return (
98
- <form ref={formRef} onSubmit={handleSubmit} className='flex flex-col gap-2'>
99
- <div>
100
- <label htmlFor='email' className='block text-sm font-medium leading-6 text-foreground'>
101
- {t('username')}
102
- </label>
103
- <div className=''>
104
- <input
105
- ref={usernameRef}
106
- id='username'
107
- name='username'
108
- type='text'
109
- // required
110
- className='block w-full rounded-md border-0 bg-input p-3 text-foreground shadow-xs outline-0 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6'
111
- />
112
- </div>
113
- </div>
114
-
115
- <div>
116
- <label htmlFor='password' className='block text-sm font-medium leading-6 text-foreground'>
117
- {t('password')}
118
- </label>
119
- <div className=''>
120
- <input
121
- ref={passwordRef}
122
- id='password'
123
- name='password'
124
- type='text'
125
- // required
126
- className='block w-full rounded-md border-0 bg-input p-3 text-foreground shadow-xs outline-0 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6'
127
- />
128
- </div>
129
- </div>
130
- {privileges && privileges.length > 0 && (
131
- <>
132
- <div className='mt-5 w-full font-semibold'>{t('adminPrivileges')}</div>
133
- <div className='flex'>
134
- <Button
135
- className='border border-foreground'
136
- type='button'
137
- variant={allChecked === true ? 'default' : 'secondary'}
138
- onClick={(event) => {
139
- event.preventDefault()
140
- event.stopPropagation()
141
- if (allChecked === true) {
142
- setAllChecked(false)
143
- } else {
144
- setAllChecked(true)
145
- }
146
- }}
147
- >
148
- {allChecked === true ? t('removeAll') : t('checkAll')}
149
- </Button>
150
- </div>
151
- <div className='mt-2 grid w-full grid-cols-1 gap-2 md-sidebar:grid-cols-2 lg-sidebar:grid-cols-3 xl-sidebar:grid-cols-4 2xl-sidebar:grid-cols-5'>
152
- {privileges.map((privilege, index: number) => {
153
- return (
154
- <AdminRoleCard
155
- key={index}
156
- privilege={privilege}
157
- allChecked={allChecked}
158
- setAllChecked={setAllChecked}
159
- />
160
- )
161
- })}
162
- </div>
163
- </>
164
- )}
165
-
166
- <div className='mt-4'>
167
- <button type='submit' className='rounded bg-blue-700 px-2 py-1 font-bold text-white'>
168
- {t('submitNewAdmin')}
169
- </button>
170
- </div>
171
- </form>
172
- )
173
- }
10
+
11
+ export default function NewAdminForm({
12
+ privileges,
13
+ action,
14
+ }: {
15
+ privileges: RouterOutputs['admins']['list']['privileges']
16
+ action: any
17
+ }) {
18
+ const t = useI18n()
19
+ const { setModal, modal, modalResponse, setModalResponse } = useModal()
20
+ const { toast } = useToast()
21
+ const formRef = React.useRef<HTMLFormElement>(null)
22
+ const [allChecked, setAllChecked] = React.useState<boolean | 'edited' | null>(null)
23
+ const usernameRef = React.useRef<HTMLInputElement>(null)
24
+ const passwordRef = React.useRef<HTMLInputElement>(null)
25
+
26
+ const mutation = trpc.admins.create.useMutation({
27
+ onError: (error) => {
28
+ setModal({
29
+ title: t('createNewAdmin'),
30
+ body: (
31
+ <div className='p-4'>
32
+ <InfoCard result={{ key: 'danger', title: error.message, status: false }} />
33
+ </div>
34
+ ),
35
+ headerColor: 'bg-red-700',
36
+ titleColor: 'text-white',
37
+ lang: 'en',
38
+ })
39
+ },
40
+
41
+ onSuccess: (data) => {
42
+ setModal(null)
43
+ setModalResponse(null)
44
+ setAllChecked(false)
45
+ action()
46
+
47
+ /**
48
+ * Empty the form
49
+ */
50
+ if (formRef.current) {
51
+ formRef.current.reset()
52
+ }
53
+
54
+ /**
55
+ * Show a success toast
56
+ */
57
+ toast({
58
+ variant: 'success',
59
+ title: t('createNewAdmin'),
60
+ description: t('itemCreatedSuccessfully'),
61
+ })
62
+ },
63
+ })
64
+
65
+ const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
66
+ e.preventDefault()
67
+
68
+ /**
69
+ * Check username and password
70
+ */
71
+ if (!usernameRef.current?.value || !passwordRef.current?.value) {
72
+ setModal({
73
+ title: t('createNewAdmin'),
74
+ body: <div className='p-4'>{t('usernamePasswordRequired')}</div>,
75
+ headerColor: 'bg-red-700',
76
+ titleColor: 'text-white',
77
+ lang: 'en',
78
+ })
79
+ return
80
+ }
81
+
82
+ const data = new FormData(e.currentTarget)
83
+ const values = Object.fromEntries(data.entries())
84
+ values.form_type = 'new'
85
+
86
+ // Convert the privileges to an array of objects
87
+ const privileges = Object.entries(values).filter(([key]) => key.includes('privileges'))
88
+ const privilegesArray = privileges.map(([key, value]) => JSON.parse(value as string))
89
+
90
+ mutation.mutate({
91
+ username: usernameRef.current.value,
92
+ password: passwordRef.current.value,
93
+ privileges: privilegesArray,
94
+ })
95
+ }
96
+
97
+ return (
98
+ <form ref={formRef} onSubmit={handleSubmit} className='flex flex-col gap-2'>
99
+ <div>
100
+ <label htmlFor='email' className='block text-sm font-medium leading-6 text-foreground'>
101
+ {t('username')}
102
+ </label>
103
+ <div className=''>
104
+ <input
105
+ ref={usernameRef}
106
+ id='username'
107
+ name='username'
108
+ type='text'
109
+ // required
110
+ className='block w-full rounded-md border-0 bg-input p-3 text-foreground shadow-xs outline-0 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6'
111
+ />
112
+ </div>
113
+ </div>
114
+
115
+ <div>
116
+ <label htmlFor='password' className='block text-sm font-medium leading-6 text-foreground'>
117
+ {t('password')}
118
+ </label>
119
+ <div className=''>
120
+ <input
121
+ ref={passwordRef}
122
+ id='password'
123
+ name='password'
124
+ type='text'
125
+ // required
126
+ className='block w-full rounded-md border-0 bg-input p-3 text-foreground shadow-xs outline-0 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6'
127
+ />
128
+ </div>
129
+ </div>
130
+ {privileges && privileges.length > 0 && (
131
+ <>
132
+ <div className='mt-5 w-full font-semibold'>{t('adminPrivileges')}</div>
133
+ <div className='flex'>
134
+ <Button
135
+ className='border border-foreground'
136
+ type='button'
137
+ variant={allChecked === true ? 'default' : 'secondary'}
138
+ onClick={(event) => {
139
+ event.preventDefault()
140
+ event.stopPropagation()
141
+ if (allChecked === true) {
142
+ setAllChecked(false)
143
+ } else {
144
+ setAllChecked(true)
145
+ }
146
+ }}
147
+ >
148
+ {allChecked === true ? t('removeAll') : t('checkAll')}
149
+ </Button>
150
+ </div>
151
+ <div className='mt-2 grid w-full grid-cols-1 gap-2 md-sidebar:grid-cols-2 lg-sidebar:grid-cols-3 xl-sidebar:grid-cols-4 2xl-sidebar:grid-cols-5'>
152
+ {privileges.map((privilege, index: number) => {
153
+ return (
154
+ <AdminRoleCard
155
+ key={index}
156
+ privilege={privilege}
157
+ allChecked={allChecked}
158
+ setAllChecked={setAllChecked}
159
+ />
160
+ )
161
+ })}
162
+ </div>
163
+ </>
164
+ )}
165
+
166
+ <div className='mt-4'>
167
+ <button type='submit' className='rounded bg-blue-700 px-2 py-1 font-bold text-white'>
168
+ {t('submitNewAdmin')}
169
+ </button>
170
+ </div>
171
+ </form>
172
+ )
173
+ }
@@ -1,24 +1,24 @@
1
- import React from 'react'
2
- // import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
3
-
4
- export default function ContainerBox({ children, title }: { children: React.ReactNode; title?: string }) {
5
- return (
6
- <>
7
- {/*<Card>
8
- <CardHeader>
9
- <CardTitle>{title}</CardTitle>
10
- </CardHeader>
11
- <CardContent>{children}</CardContent>
12
- </Card>*/}
13
-
14
- <div className='relative flex flex-col rounded-lg border border-slate-300 bg-white shadow-xs dark:border-slate-500 dark:bg-slate-900'>
15
- {title ? (
16
- <div className='rounded-t-lg px-4 py-1.5 font-bold text-black dark:bg-slate-800 dark:text-white'>
17
- {title}
18
- </div>
19
- ) : null}
20
- <div className='w-full px-4 py-2'>{children}</div>
21
- </div>
22
- </>
23
- )
24
- }
1
+ import React from 'react'
2
+ // import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
3
+
4
+ export default function ContainerBox({ children, title }: { children: React.ReactNode; title?: string }) {
5
+ return (
6
+ <>
7
+ {/*<Card>
8
+ <CardHeader>
9
+ <CardTitle>{title}</CardTitle>
10
+ </CardHeader>
11
+ <CardContent>{children}</CardContent>
12
+ </Card>*/}
13
+
14
+ <div className='relative flex flex-col rounded-lg border border-slate-300 bg-white shadow-xs dark:border-slate-500 dark:bg-slate-900'>
15
+ {title ? (
16
+ <div className='rounded-t-lg px-4 py-1.5 font-bold text-black dark:bg-slate-800 dark:text-white'>
17
+ {title}
18
+ </div>
19
+ ) : null}
20
+ <div className='w-full px-4 py-2'>{children}</div>
21
+ </div>
22
+ </>
23
+ )
24
+ }
@@ -1,21 +1,21 @@
1
- import React from 'react'
2
- import { useDraggable } from '@dnd-kit/core'
3
-
4
- function Draggable({ draggableId, children }: { draggableId: string | number; children: React.ReactNode }) {
5
- const { attributes, listeners, setNodeRef, transform } = useDraggable({
6
- id: draggableId,
7
- })
8
- const style = transform
9
- ? {
10
- transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
11
- }
12
- : undefined
13
-
14
- return (
15
- <div ref={setNodeRef} className='float-start' style={style} {...listeners} {...attributes}>
16
- {children}
17
- </div>
18
- )
19
- }
20
-
21
- export default Draggable
1
+ import React from 'react'
2
+ import { useDraggable } from '@dnd-kit/core'
3
+
4
+ function Draggable({ draggableId, children }: { draggableId: string | number; children: React.ReactNode }) {
5
+ const { attributes, listeners, setNodeRef, transform } = useDraggable({
6
+ id: draggableId,
7
+ })
8
+ const style = transform
9
+ ? {
10
+ transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
11
+ }
12
+ : undefined
13
+
14
+ return (
15
+ <div ref={setNodeRef} className='float-start' style={style} {...listeners} {...attributes}>
16
+ {children}
17
+ </div>
18
+ )
19
+ }
20
+
21
+ export default Draggable
@@ -1,20 +1,20 @@
1
- import React from 'react'
2
- import { useDroppable } from '@dnd-kit/core'
3
-
4
- function Droppable({ droppableId, children }: { droppableId: string | number; children: React.ReactNode }) {
5
- const { isOver, setNodeRef } = useDroppable({
6
- id: droppableId,
7
- })
8
-
9
- const style = {
10
- color: isOver ? 'green' : undefined,
11
- }
12
-
13
- return (
14
- <div ref={setNodeRef} style={style}>
15
- {children}
16
- </div>
17
- )
18
- }
19
-
20
- export default Droppable
1
+ import React from 'react'
2
+ import { useDroppable } from '@dnd-kit/core'
3
+
4
+ function Droppable({ droppableId, children }: { droppableId: string | number; children: React.ReactNode }) {
5
+ const { isOver, setNodeRef } = useDroppable({
6
+ id: droppableId,
7
+ })
8
+
9
+ const style = {
10
+ color: isOver ? 'green' : undefined,
11
+ }
12
+
13
+ return (
14
+ <div ref={setNodeRef} style={style}>
15
+ {children}
16
+ </div>
17
+ )
18
+ }
19
+
20
+ export default Droppable
@@ -1,18 +1,18 @@
1
- import React from 'react'
2
- import { useSortable } from '@dnd-kit/sortable'
3
- import { CSS } from '@dnd-kit/utilities'
4
-
5
- export default function SortableItem({ id, children }: { id: string | number; children: React.ReactNode }) {
6
- const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: id })
7
-
8
- const style = {
9
- transform: CSS.Transform.toString(transform),
10
- transition,
11
- }
12
-
13
- return (
14
- <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
15
- {children}
16
- </div>
17
- )
18
- }
1
+ import React from 'react'
2
+ import { useSortable } from '@dnd-kit/sortable'
3
+ import { CSS } from '@dnd-kit/utilities'
4
+
5
+ export default function SortableItem({ id, children }: { id: string | number; children: React.ReactNode }) {
6
+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: id })
7
+
8
+ const style = {
9
+ transform: CSS.Transform.toString(transform),
10
+ transition,
11
+ }
12
+
13
+ return (
14
+ <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
15
+ {children}
16
+ </div>
17
+ )
18
+ }
@@ -1,17 +1,17 @@
1
- import { Alert, AlertDescription } from '@/components/ui/alert'
2
- import { ExclamationTriangleIcon } from '@radix-ui/react-icons'
3
-
4
- export default function ErrorComponent({ message }: { message: string }) {
5
- return (
6
- <div className='px-4'>
7
- <Alert variant='info' className='my-8'>
8
- <AlertDescription className='text-md font-bold'>
9
- <div className='flex items-center gap-1.5'>
10
- <ExclamationTriangleIcon className='size-5' /> {message}
11
- </div>
12
- </AlertDescription>
13
- </Alert>
14
- </div>
15
- )
16
-
1
+ import { Alert, AlertDescription } from '@/components/ui/alert'
2
+ import { ExclamationTriangleIcon } from '@radix-ui/react-icons'
3
+
4
+ export default function ErrorComponent({ message }: { message: string }) {
5
+ return (
6
+ <div className='px-4'>
7
+ <Alert variant='info' className='my-8'>
8
+ <AlertDescription className='text-md font-bold'>
9
+ <div className='flex items-center gap-1.5'>
10
+ <ExclamationTriangleIcon className='size-5' /> {message}
11
+ </div>
12
+ </AlertDescription>
13
+ </Alert>
14
+ </div>
15
+ )
16
+
17
17
  }