create-nextjs-cms 0.5.23 → 0.5.24

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 (191) hide show
  1. package/package.json +5 -7
  2. package/templates/default/components/NewPage.tsx +2 -2
  3. package/templates/default/components/ProgressBar.tsx +46 -22
  4. package/templates/default/components/form/DateRangeFormInput.tsx +8 -6
  5. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  6. package/templates/default/components/form/inputs/DateFormInput.tsx +82 -34
  7. package/templates/default/components/form/inputs/MultipleSelectFormInput.tsx +40 -107
  8. package/templates/default/components/form/inputs/RichTextFormInput.tsx +2 -0
  9. package/templates/default/components/form/inputs/TagsFormInput.tsx +115 -26
  10. package/templates/default/components/form/inputs/TextFormInput.tsx +1 -1
  11. package/templates/default/components/multi-select.tsx +1144 -0
  12. package/templates/default/components/ui/badge.tsx +16 -12
  13. package/templates/default/components/ui/button.tsx +35 -30
  14. package/templates/default/components/ui/calendar.tsx +145 -47
  15. package/templates/default/components/ui/command.tsx +184 -0
  16. package/templates/default/components/ui/dialog.tsx +143 -0
  17. package/templates/default/components/ui/popover.tsx +39 -22
  18. package/templates/default/components/ui/progress.tsx +31 -0
  19. package/templates/default/components/ui/select.tsx +150 -149
  20. package/templates/default/components/ui/separator.tsx +28 -0
  21. package/templates/default/components.json +8 -3
  22. package/templates/default/{postinstall.js → lib/postinstall.js} +1 -1
  23. package/templates/default/lib/utils.ts +6 -0
  24. package/templates/default/{proxy.ts → middleware.ts} +3 -2
  25. package/templates/default/next-env.d.ts +1 -1
  26. package/templates/default/package.json +41 -52
  27. package/templates/default/public/tinymce/CHANGELOG.md +155 -0
  28. package/templates/default/public/tinymce/README.md +12 -12
  29. package/templates/default/public/tinymce/bower.json +1 -1
  30. package/templates/default/public/tinymce/composer.json +2 -2
  31. package/templates/default/public/tinymce/icons/default/icons.js +40 -32
  32. package/templates/default/public/tinymce/icons/default/icons.min.js +1 -1
  33. package/templates/default/public/tinymce/license.md +7 -4
  34. package/templates/default/public/tinymce/models/dom/model.js +36 -50
  35. package/templates/default/public/tinymce/models/dom/model.min.js +1 -1
  36. package/templates/default/public/tinymce/notices.txt +2 -2
  37. package/templates/default/public/tinymce/package.json +2 -2
  38. package/templates/default/public/tinymce/plugins/accordion/plugin.js +45 -21
  39. package/templates/default/public/tinymce/plugins/accordion/plugin.min.js +1 -1
  40. package/templates/default/public/tinymce/plugins/advlist/plugin.js +8 -6
  41. package/templates/default/public/tinymce/plugins/advlist/plugin.min.js +1 -1
  42. package/templates/default/public/tinymce/plugins/anchor/plugin.js +1 -1
  43. package/templates/default/public/tinymce/plugins/autolink/plugin.js +3 -6
  44. package/templates/default/public/tinymce/plugins/autolink/plugin.min.js +1 -1
  45. package/templates/default/public/tinymce/plugins/autoresize/plugin.js +4 -6
  46. package/templates/default/public/tinymce/plugins/autoresize/plugin.min.js +1 -1
  47. package/templates/default/public/tinymce/plugins/autosave/plugin.js +4 -7
  48. package/templates/default/public/tinymce/plugins/autosave/plugin.min.js +1 -1
  49. package/templates/default/public/tinymce/plugins/charmap/plugin.js +8 -8
  50. package/templates/default/public/tinymce/plugins/charmap/plugin.min.js +1 -1
  51. package/templates/default/public/tinymce/plugins/code/plugin.js +3 -2
  52. package/templates/default/public/tinymce/plugins/code/plugin.min.js +1 -1
  53. package/templates/default/public/tinymce/plugins/codesample/plugin.js +11 -10
  54. package/templates/default/public/tinymce/plugins/codesample/plugin.min.js +2 -2
  55. package/templates/default/public/tinymce/plugins/directionality/plugin.js +9 -11
  56. package/templates/default/public/tinymce/plugins/directionality/plugin.min.js +1 -1
  57. package/templates/default/public/tinymce/plugins/emoticons/plugin.js +7 -7
  58. package/templates/default/public/tinymce/plugins/emoticons/plugin.min.js +1 -1
  59. package/templates/default/public/tinymce/plugins/fullscreen/plugin.js +11 -13
  60. package/templates/default/public/tinymce/plugins/fullscreen/plugin.min.js +1 -1
  61. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/bg-BG.js +93 -0
  62. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/fr-FR.js +93 -0
  63. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/he-IL.js +93 -0
  64. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/hu-HU.js +93 -0
  65. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/ko-KR.js +93 -0
  66. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/nb-NO.js +93 -0
  67. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/pt-BR.js +93 -0
  68. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/pt-PT.js +93 -0
  69. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/sl-SI.js +93 -0
  70. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/sv-SE.js +93 -0
  71. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/th-TH.js +93 -0
  72. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/zh-CN.js +87 -0
  73. package/templates/default/public/tinymce/plugins/help/js/i18n/keynav/zh-TW.js +93 -0
  74. package/templates/default/public/tinymce/plugins/help/plugin.js +15 -17
  75. package/templates/default/public/tinymce/plugins/help/plugin.min.js +1 -1
  76. package/templates/default/public/tinymce/plugins/image/plugin.js +34 -32
  77. package/templates/default/public/tinymce/plugins/image/plugin.min.js +1 -1
  78. package/templates/default/public/tinymce/plugins/importcss/plugin.js +4 -6
  79. package/templates/default/public/tinymce/plugins/importcss/plugin.min.js +1 -1
  80. package/templates/default/public/tinymce/plugins/insertdatetime/plugin.js +4 -3
  81. package/templates/default/public/tinymce/plugins/insertdatetime/plugin.min.js +1 -1
  82. package/templates/default/public/tinymce/plugins/link/plugin.js +170 -38
  83. package/templates/default/public/tinymce/plugins/link/plugin.min.js +1 -1
  84. package/templates/default/public/tinymce/plugins/lists/plugin.js +111 -2053
  85. package/templates/default/public/tinymce/plugins/lists/plugin.min.js +1 -1
  86. package/templates/default/public/tinymce/plugins/media/plugin.js +15 -23
  87. package/templates/default/public/tinymce/plugins/media/plugin.min.js +1 -1
  88. package/templates/default/public/tinymce/plugins/nonbreaking/plugin.js +1 -1
  89. package/templates/default/public/tinymce/plugins/pagebreak/plugin.js +1 -1
  90. package/templates/default/public/tinymce/plugins/preview/plugin.js +88 -10
  91. package/templates/default/public/tinymce/plugins/preview/plugin.min.js +1 -1
  92. package/templates/default/public/tinymce/plugins/quickbars/plugin.js +9 -9
  93. package/templates/default/public/tinymce/plugins/quickbars/plugin.min.js +1 -1
  94. package/templates/default/public/tinymce/plugins/save/plugin.js +1 -1
  95. package/templates/default/public/tinymce/plugins/searchreplace/plugin.js +10 -13
  96. package/templates/default/public/tinymce/plugins/searchreplace/plugin.min.js +1 -1
  97. package/templates/default/public/tinymce/plugins/table/plugin.js +13 -24
  98. package/templates/default/public/tinymce/plugins/table/plugin.min.js +1 -1
  99. package/templates/default/public/tinymce/plugins/visualblocks/plugin.js +1 -1
  100. package/templates/default/public/tinymce/plugins/visualchars/plugin.js +9 -10
  101. package/templates/default/public/tinymce/plugins/visualchars/plugin.min.js +1 -1
  102. package/templates/default/public/tinymce/plugins/wordcount/plugin.js +1 -1
  103. package/templates/default/public/tinymce/skins/content/dark/content.min.ts +3 -0
  104. package/templates/default/public/tinymce/skins/content/dark/content.ts +3 -0
  105. package/templates/default/public/tinymce/skins/content/default/content.min.ts +3 -0
  106. package/templates/default/public/tinymce/skins/content/default/content.ts +3 -0
  107. package/templates/default/public/tinymce/skins/content/document/content.min.ts +3 -0
  108. package/templates/default/public/tinymce/skins/content/document/content.ts +3 -0
  109. package/templates/default/public/tinymce/skins/content/tinymce-5/content.min.ts +3 -0
  110. package/templates/default/public/tinymce/skins/content/tinymce-5/content.ts +3 -0
  111. package/templates/default/public/tinymce/skins/content/tinymce-5-dark/content.min.ts +3 -0
  112. package/templates/default/public/tinymce/skins/content/tinymce-5-dark/content.ts +3 -0
  113. package/templates/default/public/tinymce/skins/content/writer/content.min.ts +3 -0
  114. package/templates/default/public/tinymce/skins/content/writer/content.ts +3 -0
  115. package/templates/default/public/tinymce/skins/ui/oxide/content.css +144 -0
  116. package/templates/default/public/tinymce/skins/ui/oxide/content.inline.css +144 -0
  117. package/templates/default/public/tinymce/skins/ui/oxide/content.inline.js +1 -1
  118. package/templates/default/public/tinymce/skins/ui/oxide/content.inline.min.css +1 -1
  119. package/templates/default/public/tinymce/skins/ui/oxide/content.inline.min.ts +116 -0
  120. package/templates/default/public/tinymce/skins/ui/oxide/content.inline.ts +116 -0
  121. package/templates/default/public/tinymce/skins/ui/oxide/content.js +1 -1
  122. package/templates/default/public/tinymce/skins/ui/oxide/content.min.css +1 -1
  123. package/templates/default/public/tinymce/skins/ui/oxide/content.min.ts +116 -0
  124. package/templates/default/public/tinymce/skins/ui/oxide/content.ts +116 -0
  125. package/templates/default/public/tinymce/skins/ui/oxide/skin.css +923 -449
  126. package/templates/default/public/tinymce/skins/ui/oxide/skin.js +1 -1
  127. package/templates/default/public/tinymce/skins/ui/oxide/skin.min.css +1 -1
  128. package/templates/default/public/tinymce/skins/ui/oxide/skin.min.ts +507 -0
  129. package/templates/default/public/tinymce/skins/ui/oxide/skin.shadowdom.min.ts +9 -0
  130. package/templates/default/public/tinymce/skins/ui/oxide/skin.shadowdom.ts +9 -0
  131. package/templates/default/public/tinymce/skins/ui/oxide/skin.ts +507 -0
  132. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.css +144 -0
  133. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.css +144 -0
  134. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.js +1 -1
  135. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.min.css +1 -1
  136. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.min.ts +116 -0
  137. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.inline.ts +116 -0
  138. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.js +1 -1
  139. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.min.css +1 -1
  140. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.min.ts +116 -0
  141. package/templates/default/public/tinymce/skins/ui/oxide-dark/content.ts +116 -0
  142. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.css +926 -452
  143. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.js +1 -1
  144. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.min.css +1 -1
  145. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.min.ts +507 -0
  146. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.ts +9 -0
  147. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.shadowdom.ts +9 -0
  148. package/templates/default/public/tinymce/skins/ui/oxide-dark/skin.ts +507 -0
  149. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.css +144 -0
  150. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.css +144 -0
  151. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.js +1 -1
  152. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.min.css +1 -1
  153. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.min.ts +116 -0
  154. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.inline.ts +116 -0
  155. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.js +1 -1
  156. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.min.css +1 -1
  157. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.min.ts +116 -0
  158. package/templates/default/public/tinymce/skins/ui/tinymce-5/content.ts +116 -0
  159. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.css +924 -450
  160. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.js +1 -1
  161. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.min.css +1 -1
  162. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.min.ts +508 -0
  163. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.ts +9 -0
  164. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.shadowdom.ts +9 -0
  165. package/templates/default/public/tinymce/skins/ui/tinymce-5/skin.ts +508 -0
  166. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.css +144 -0
  167. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.css +144 -0
  168. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.js +1 -1
  169. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +1 -1
  170. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.min.ts +116 -0
  171. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.inline.ts +116 -0
  172. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.js +1 -1
  173. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.min.css +1 -1
  174. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.min.ts +116 -0
  175. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/content.ts +116 -0
  176. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.css +925 -451
  177. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -1
  178. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -1
  179. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.min.ts +508 -0
  180. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.ts +9 -0
  181. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.ts +9 -0
  182. package/templates/default/public/tinymce/skins/ui/tinymce-5-dark/skin.ts +508 -0
  183. package/templates/default/public/tinymce/themes/silver/theme.js +543 -593
  184. package/templates/default/public/tinymce/themes/silver/theme.min.js +1 -1
  185. package/templates/default/public/tinymce/tinymce.d.ts +559 -496
  186. package/templates/default/public/tinymce/tinymce.js +6788 -3964
  187. package/templates/default/public/tinymce/tinymce.min.js +3 -4
  188. package/templates/default/styles/globals.css +132 -107
  189. package/templates/default/tsconfig.json +45 -45
  190. package/templates/default/.prettierrc.json +0 -19
  191. package/templates/default/eslint.config.mjs +0 -38
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nextjs-cms",
3
- "version": "0.5.23",
3
+ "version": "0.5.24",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "create-nextjs-cms": "./dist/index.js"
@@ -15,20 +15,18 @@
15
15
  "fs-extra": "^11.3.0",
16
16
  "glob": "^11.0.3",
17
17
  "js-yaml": "^4.1.1",
18
- "prompts": "^2.4.2",
19
- "nextjs-cms": "0.5.23"
18
+ "prompts": "^2.4.2"
20
19
  },
21
20
  "devDependencies": {
22
21
  "@types/fs-extra": "^11.0.4",
23
22
  "@types/js-yaml": "^4.0.9",
24
- "@types/minimatch": "^5.1.2",
25
23
  "@types/prompts": "^2.4.9",
26
24
  "eslint": "^9.12.0",
27
25
  "prettier": "^3.3.3",
28
- "tsx": "^4.21.0",
29
- "typescript": "^5.9.3",
30
- "@lzcms/prettier-config": "0.1.0",
26
+ "tsx": "^4.20.6",
27
+ "typescript": "^5.9.2",
31
28
  "@lzcms/eslint-config": "0.3.0",
29
+ "@lzcms/prettier-config": "0.1.0",
32
30
  "@lzcms/tsconfig": "0.1.0"
33
31
  },
34
32
  "prettier": "@lzcms/prettier-config",
@@ -181,8 +181,8 @@ export default function NewPage({
181
181
  {isError ? <div>{error?.message}</div> : null}
182
182
  {data ? (
183
183
  <div className='flex w-full flex-col'>
184
- <div className='relative z-1 border-b-2 p-8 pt-12 font-extrabold text-foreground'>
185
- <div className='absolute left-0 top-0 z-2 h-4 w-full bg-linear-to-r from-emerald-800 via-emerald-400 to-sky-600'></div>
184
+ <div className='text-foreground relative z-1 border-b-2 p-8 pt-12 font-extrabold'>
185
+ <div className='absolute top-0 left-0 z-2 h-4 w-full bg-linear-to-r from-emerald-800 via-emerald-400 to-sky-600'></div>
186
186
  <h1 className='pb-4 text-4xl'>{data.section?.title.section}</h1>
187
187
  <span>
188
188
  /{getString('new')} {data.section?.title.singular}
@@ -1,24 +1,48 @@
1
- import * as React from 'react'
2
- import { styled } from '@mui/material/styles'
3
- import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress'
1
+ 'use client'
4
2
 
5
- const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
6
- height: 10,
7
- borderRadius: 5,
8
- [`&.${linearProgressClasses.colorPrimary}`]: {
9
- backgroundColor: theme.palette.grey[theme.palette.mode === 'light' ? 200 : 800],
10
- },
11
- [`& .${linearProgressClasses.bar}`]: {
12
- borderRadius: 5,
13
- backgroundColor: theme.palette.mode === 'light' ? '#1a90ff' : '#308fe8',
14
- },
15
- }))
16
- export default function ProgressBar({
17
- value,
18
- variant,
19
- }: {
20
- value: number
21
- variant?: 'determinate' | 'indeterminate' | 'buffer' | 'query'
22
- }) {
23
- return <BorderLinearProgress variant={variant} value={value} />
3
+ import { useTheme } from 'next-themes'
4
+ import { Progress } from '@/components/ui/progress'
5
+
6
+ export default function ProgressBar({ value, variant }: { value: number; variant?: 'determinate' | 'query' }) {
7
+ const { theme } = useTheme()
8
+ const isDark = theme === 'dark'
9
+
10
+ // Colors that match the original Material-UI version exactly
11
+ const bgColor = isDark ? '#424242' : '#eeeeee' // grey[800] : grey[200]
12
+ const progressColor = isDark ? '#308fe8' : '#1a90ff'
13
+
14
+ // Query variant shows indeterminate animation
15
+ const shouldShowIndeterminate = variant === 'query'
16
+
17
+ if (shouldShowIndeterminate) {
18
+ return (
19
+ <div
20
+ className='relative h-[10px] w-full overflow-hidden rounded-[5px]'
21
+ style={{ backgroundColor: bgColor }}
22
+ >
23
+ <div
24
+ className='h-full rounded-[5px]'
25
+ style={{
26
+ backgroundColor: progressColor,
27
+ width: '30%',
28
+ animation: 'progress-indeterminate 1.5s ease-in-out infinite',
29
+ }}
30
+ />
31
+ </div>
32
+ )
33
+ }
34
+
35
+ return (
36
+ <div
37
+ className='progress-bar-custom relative w-full'
38
+ style={
39
+ {
40
+ '--progress-bg': bgColor,
41
+ '--progress-fg': progressColor,
42
+ } as React.CSSProperties
43
+ }
44
+ >
45
+ <Progress value={value} className='h-[10px] rounded-[5px] border-0 p-0' />
46
+ </div>
47
+ )
24
48
  }
@@ -1,8 +1,8 @@
1
1
  'use client'
2
2
 
3
3
  import * as React from 'react'
4
- import { addDays, format } from 'date-fns'
5
- import { DateRange } from 'react-day-picker'
4
+ import dayjs from 'dayjs'
5
+ import type { DateRange } from 'react-day-picker'
6
6
 
7
7
  import { cn } from 'nextjs-cms/utils'
8
8
  import { Button } from '@/components/ui/button'
@@ -13,7 +13,9 @@ import { CalendarIcon } from '@radix-ui/react-icons'
13
13
  export function DatePickerWithRange({ className }: React.HTMLAttributes<HTMLDivElement>) {
14
14
  const [date, setDate] = React.useState<DateRange | undefined>({
15
15
  from: new Date(2020, 0, 20),
16
- to: addDays(new Date(2023, 0, 20), 20),
16
+ to: dayjs(new Date(2023, 0, 20))
17
+ .add(20, 'day')
18
+ .toDate(),
17
19
  })
18
20
 
19
21
  return (
@@ -29,10 +31,10 @@ export function DatePickerWithRange({ className }: React.HTMLAttributes<HTMLDivE
29
31
  {date?.from ? (
30
32
  date.to ? (
31
33
  <>
32
- {format(date.from, 'LLL dd, y')} - {format(date.to, 'LLL dd, y')}
34
+ {dayjs(date.from).format('MMM DD, YYYY')} - {dayjs(date.to).format('MMM DD, YYYY')}
33
35
  </>
34
36
  ) : (
35
- format(date.from, 'LLL dd, y')
37
+ dayjs(date.from).format('MMM DD, YYYY')
36
38
  )
37
39
  ) : (
38
40
  <span>Pick a date</span>
@@ -41,7 +43,7 @@ export function DatePickerWithRange({ className }: React.HTMLAttributes<HTMLDivE
41
43
  </PopoverTrigger>
42
44
  <PopoverContent className='w-auto p-0' align='start'>
43
45
  <Calendar
44
- initialFocus
46
+ autoFocus
45
47
  mode='range'
46
48
  defaultMonth={date?.from}
47
49
  selected={date}
@@ -8,4 +8,4 @@ export const revalidate = 0
8
8
 
9
9
  // @refresh reset
10
10
 
11
- export const sectionSchemaLastUpdated = 1765925556117
11
+ export const sectionSchemaLastUpdated = 1766066280270
@@ -1,15 +1,16 @@
1
1
  import React from 'react'
2
2
  import dayjs from 'dayjs'
3
3
  import FormInputElement from '@/components/form/FormInputElement'
4
- import { format } from 'date-fns'
5
- import { cn } from 'nextjs-cms/utils'
6
4
  import { Button } from '@/components/ui/button'
7
5
  import { Calendar } from '@/components/ui/calendar'
8
6
  import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
9
- import { CalendarIcon } from '@radix-ui/react-icons'
7
+ import { CalendarIcon, ChevronDownIcon } from '@radix-ui/react-icons'
10
8
  import getString from 'nextjs-cms/translations'
11
9
  import { DateFieldClientConfig } from 'nextjs-cms/core/fields'
12
10
  import { useController, useFormContext } from 'react-hook-form'
11
+ import { Input } from '@/components/ui/input'
12
+ import { Label } from '@/components/ui/label'
13
+ import { Clock2Icon } from 'lucide-react'
13
14
 
14
15
  const seasonEmoji: Record<string, string> = {
15
16
  winter: '⛄️',
@@ -28,23 +29,29 @@ const getSeason = (month: Date): string => {
28
29
 
29
30
  const formatCaption = (month: Date, options?: any) => {
30
31
  const season = getSeason(month)
31
- return seasonEmoji[season] + ' ' + format(month, 'LLLL', { locale: options?.locale })
32
+ return seasonEmoji[season] + ' ' + dayjs(month).format('MMMM')
32
33
  }
33
34
 
34
35
  export default function DateFormInput({ input }: { input: DateFieldClientConfig }) {
35
36
  const { control } = useFormContext()
37
+ const [open, setOpen] = React.useState(false)
36
38
  const {
37
39
  field,
38
40
  fieldState: { invalid, isTouched, isDirty, error },
39
41
  } = useController({
40
42
  name: input.name,
41
43
  control,
42
- // defaultValue: input.value ?? undefined,
44
+ defaultValue: input.value
45
+ ? dayjs(input.value).isValid()
46
+ ? dayjs(input.value).toDate()
47
+ : undefined
48
+ : undefined,
43
49
  })
44
50
 
45
51
  const [date, setDate] = React.useState<Date | undefined>(
46
- dayjs(input.value).isValid() ? dayjs(input.value).toDate() : undefined,
52
+ input.value ? (dayjs(input.value).isValid() ? dayjs(input.value).toDate() : undefined) : undefined,
47
53
  )
54
+
48
55
  return (
49
56
  <FormInputElement
50
57
  validationError={error}
@@ -58,48 +65,89 @@ export default function DateFormInput({ input }: { input: DateFieldClientConfig
58
65
  disabled={field.disabled}
59
66
  name={field.name}
60
67
  onBlur={field.onBlur}
61
- value={date ? format(date, 'yyyy-MM-dd') : undefined}
68
+ value={
69
+ date
70
+ ? dayjs(date).format(input.format !== 'date' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')
71
+ : undefined
72
+ }
62
73
  ref={field.ref}
63
74
  className='rounded border p-2'
64
75
  />
65
76
 
66
- <div className='flex flex-col items-start gap-2'>
67
- <Popover>
68
- <PopoverTrigger asChild>
69
- <Button
70
- variant={'outline'}
71
- className={cn(
72
- 'min-w-[250px] justify-start rounded bg-input px-3 py-6 text-start font-normal text-foreground shadow-xs outline-0 ring-2 ring-gray-300 hover:ring-gray-400 focus:ring-blue-500',
73
- !date && 'text-muted-foreground',
74
- )}
75
- >
76
- <CalendarIcon className='mr-2 h-4 w-4' />
77
- {date ? format(date, 'PPP') : <span>Pick a date</span>}
78
- </Button>
79
- </PopoverTrigger>
80
- <PopoverContent className='w-auto p-0'>
81
- <Calendar
82
- mode='single'
83
- selected={date}
84
- onSelect={(date) => {
85
- setDate(date)
86
- field.onChange(date)
77
+ <div className='flex flex-row items-start gap-2'>
78
+ <div>
79
+ <Popover open={open} onOpenChange={setOpen}>
80
+ <PopoverTrigger asChild>
81
+ <Button variant='outline' id='date' className='justify-between font-normal'>
82
+ <div className='flex items-center gap-2'>
83
+ <CalendarIcon />
84
+ {date ? dayjs(date).format('MMMM D, YYYY') : <span>Pick a date</span>}
85
+ </div>
86
+ <ChevronDownIcon />
87
+ </Button>
88
+ </PopoverTrigger>
89
+ <PopoverContent className='w-auto overflow-hidden p-0' align='start'>
90
+ <Calendar
91
+ endMonth={new Date(2099, 11)}
92
+ mode='single'
93
+ captionLayout='dropdown'
94
+ selected={date}
95
+ onSelect={(newDate) => {
96
+ /**
97
+ * We should preserve the time from the previous date if it is set
98
+ */
99
+ if (input.format !== 'date') {
100
+ const [hours, minutes, seconds] = dayjs(date)
101
+ .format('HH:mm:ss')
102
+ .split(':')
103
+ .map(Number)
104
+ newDate?.setHours(hours ?? 0, minutes ?? 0, seconds ?? 0, 0)
105
+ }
106
+ setDate(newDate)
107
+ field.onChange(newDate)
108
+ }}
109
+ autoFocus
110
+ className='rounded-lg border'
111
+ formatters={{ formatCaption }}
112
+ />
113
+ </PopoverContent>
114
+ </Popover>
115
+ </div>
116
+
117
+ {input.format !== 'date' ? (
118
+ <div className='relative flex items-center gap-2'>
119
+ <Clock2Icon className='text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none' />
120
+ <Input
121
+ type='time'
122
+ step='1'
123
+ defaultValue={'--:--:--'}
124
+ value={date ? dayjs(date).format('HH:mm:ss') : '--:--:--'}
125
+ onChange={(e) => {
126
+ const time = e.target.value
127
+ if (time && date) {
128
+ const [hours, minutes, seconds] = time.split(':').map(Number)
129
+ const newDate = new Date(date)
130
+ newDate.setHours(hours ?? 0, minutes ?? 0, seconds ?? 0, 0)
131
+ setDate(newDate)
132
+ field.onChange(newDate)
133
+ }
87
134
  }}
88
- initialFocus
89
- formatters={{ formatCaption }}
135
+ className='appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none'
90
136
  />
91
- </PopoverContent>
92
- </Popover>
137
+ </div>
138
+ ) : null}
139
+
93
140
  <Button
141
+ className='px-1.5'
94
142
  onClick={() => {
95
143
  setDate(undefined)
96
144
  field.onChange(undefined)
97
145
  }}
98
146
  variant='default'
99
147
  type='button'
100
- size='sm'
148
+ size='default'
101
149
  >
102
- {getString('cancel')}
150
+ {getString('unset')}
103
151
  </Button>
104
152
  </div>
105
153
  </FormInputElement>
@@ -1,16 +1,10 @@
1
1
  import FormInputElement from '@/components/form/FormInputElement'
2
- import { Autocomplete, Checkbox, Chip, TextField } from '@mui/material'
3
2
  import { useEffect, useState } from 'react'
4
3
  import * as React from 'react'
5
- import { useTheme } from 'next-themes'
6
-
7
- import { styled } from '@mui/material/styles'
8
4
  import { SelectMultipleFieldClientConfig, SelectOption } from 'nextjs-cms/core/fields'
9
- import { Square, CheckSquare2 } from 'lucide-react'
10
5
  import { useController, useFormContext } from 'react-hook-form'
6
+ import { MultiSelect, MultiSelectOption } from '@/components/multi-select'
11
7
 
12
- const icon = <Square fontSize='small' />
13
- const checkedIcon = <CheckSquare2 fontSize='small' />
14
8
  export default function MultipleSelectFormInput({ input }: { input: SelectMultipleFieldClientConfig }) {
15
9
  const { control } = useFormContext()
16
10
  const {
@@ -23,42 +17,29 @@ export default function MultipleSelectFormInput({ input }: { input: SelectMultip
23
17
  })
24
18
 
25
19
  const [value, setValue] = useState<SelectOption[] | undefined>([])
26
- const { theme } = useTheme()
27
20
 
28
- const borderColor = theme === 'dark' ? 'rgba(66,72,79,0.46)' : 'rgb(204,204,204)'
29
- const darkColor = 'rgba(66,72,79,0.46)' // Replace with the actual color from your screenshot
30
- const lightColor = '#f8f9fa' // Replace with the actual color from your screenshot
31
- const textColor = theme === 'dark' ? '#f8f9fa' : '#111111'
32
- const placeholderColor = theme === 'dark' ? '#bdbdbd' : '#a1a1a1'
21
+ // Convert SelectOption[] to MultiSelectOption[]
22
+ const convertToMultiSelectOptions = (options: SelectOption[] | undefined): MultiSelectOption[] => {
23
+ if (!options) return []
24
+ return options.map((option) => ({
25
+ label: option.label.toString(),
26
+ value: option.value.toString(),
27
+ }))
28
+ }
33
29
 
34
- // Custom styled TextField for Autocomplete
35
- const CustomTextField = styled(TextField)({
36
- '& .MuiFormLabel-root': {
37
- color: placeholderColor,
38
- },
39
- '& label.Mui-focused': {
40
- color: placeholderColor,
41
- },
42
- '& .MuiInput-underline:after': {
43
- borderBottomColor: theme === 'dark' ? lightColor : darkColor,
44
- },
45
- '& .MuiOutlinedInput-root': {
46
- '& fieldset': {
47
- borderColor: borderColor,
48
- borderWidth: 2,
49
- borderRadius: 8,
50
- },
51
- '&:hover fieldset': {
52
- borderColor: theme === 'dark' ? lightColor : darkColor,
53
- },
54
- '&.Mui-focused fieldset': {
55
- borderColor: '#5572fa',
56
- },
57
- '& input': {
58
- color: textColor,
59
- },
60
- },
61
- })
30
+ // Convert string[] to SelectOption[]
31
+ const convertFromStringArray = (values: string[], options: SelectOption[] | undefined): SelectOption[] => {
32
+ if (!options || !values) return []
33
+ return values
34
+ .map((value) => options.find((option) => option.value.toString() === value))
35
+ .filter(Boolean) as SelectOption[]
36
+ }
37
+
38
+ // Convert SelectOption[] to string[]
39
+ const convertToStringArray = (options: SelectOption[] | undefined): string[] => {
40
+ if (!options) return []
41
+ return options.map((option) => option.value.toString())
42
+ }
62
43
 
63
44
  useEffect(() => {
64
45
  if (input.value && input.value?.length > 0) {
@@ -66,6 +47,15 @@ export default function MultipleSelectFormInput({ input }: { input: SelectMultip
66
47
  }
67
48
  }, [input.value])
68
49
 
50
+ const multiSelectOptions = convertToMultiSelectOptions(input.options)
51
+ const currentValue = convertToStringArray(field.value || [])
52
+
53
+ const handleValueChange = (newValues: string[]) => {
54
+ const selectOptions = convertFromStringArray(newValues, input.options)
55
+ field.onChange(selectOptions)
56
+ setValue(selectOptions)
57
+ }
58
+
69
59
  return (
70
60
  <FormInputElement validationError={error} label={input.label} required={input.required}>
71
61
  <input
@@ -78,72 +68,15 @@ export default function MultipleSelectFormInput({ input }: { input: SelectMultip
78
68
  value={JSON.stringify(field.value)}
79
69
  />
80
70
 
81
- <Autocomplete
82
- className=''
83
- multiple
84
- options={input.options ? input.options : []}
85
- disableCloseOnSelect
86
- getOptionLabel={(option) => option.label.toString()}
87
- renderOption={(props, option, { selected }) => (
88
- <li {...props}>
89
- <Checkbox icon={icon} checkedIcon={checkedIcon} style={{ marginRight: 8 }} checked={selected} />
90
- {option.label}
91
- </li>
92
- )}
93
- sx={{
94
- '& .MuiAutocomplete-inputRoot': {
95
- color: lightColor, // text color
96
- '& .MuiAutocomplete-endAdornment': {
97
- color: lightColor,
98
- },
99
- },
100
- '& .MuiAutocomplete-popupIndicator': {
101
- color: lightColor,
102
- },
103
- '& .MuiAutocomplete-clearIndicator': {
104
- color: lightColor,
105
- },
106
- '& .MuiPaper-root': {
107
- bgcolor: darkColor, // dropdown background color
108
- color: lightColor, // option text color
109
- '& .MuiAutocomplete-option': {
110
- '&:hover': {
111
- bgcolor: lightColor, // option hover color
112
- color: darkColor,
113
- },
114
- '&[aria-selected="true"]': {
115
- bgcolor: lightColor, // option selected color
116
- color: darkColor,
117
- },
118
- '&[data-focus="true"]': {
119
- bgcolor: lightColor, // option focused color
120
- color: darkColor,
121
- },
122
- },
123
- },
124
- }}
125
- defaultValue={input.value ? input.value : []}
126
- renderInput={(params) => (
127
- <CustomTextField
128
- className='w-full bg-input text-foreground'
129
- {...params}
130
- label={input.label}
131
- placeholder={input.label}
132
- />
133
- )}
134
- isOptionEqualToValue={(option, value) => option.value.toString() === value.value.toString()}
135
- onChange={(event, newInputValue) => {
136
- if (newInputValue) {
137
- field.onChange(newInputValue)
138
- setValue(newInputValue)
139
- }
140
- }}
141
- disableClearable={true}
142
- renderTags={(tagValue, getTagProps) => {
143
- return tagValue.map((option, index) => (
144
- <Chip color='primary' {...getTagProps({ index })} key={option.value} label={option.label} />
145
- ))
146
- }}
71
+ <MultiSelect
72
+ variant='default'
73
+ maxCount={100}
74
+ options={multiSelectOptions}
75
+ onValueChange={handleValueChange}
76
+ defaultValue={currentValue}
77
+ // placeholder={input.label || 'Select options'}
78
+ disabled={field.disabled}
79
+ className='w-full py-3 ring-2 ring-gray-300'
147
80
  />
148
81
  </FormInputElement>
149
82
  )
@@ -86,6 +86,8 @@ export default function RichTextFormInput({ input }: { input: RichTextFieldClien
86
86
  required={input.required}
87
87
  >
88
88
  <Editor
89
+ api-key='no-api-key'
90
+ licenseKey='gpl'
89
91
  // TODO: Is this expensive?
90
92
  onEditorChange={(content) => {
91
93
  setValue(input.name, content, { shouldValidate: true })