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,166 +1,166 @@
1
- 'use client'
2
-
3
- import { Suspense, useEffect, useRef, useState } from 'react'
4
- import { useModal } from '@/components/feedback/modal-context'
5
- import classNames from 'classnames'
6
- import { X, Loader2 } from 'lucide-react'
7
-
8
- import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/custom-dialog'
9
-
10
- function ModalLoadingFallback() {
11
- return (
12
- <div className='flex min-h-[200px] items-center justify-center p-8'>
13
- <Loader2 className='h-8 w-8 animate-spin text-muted-foreground' />
14
- </div>
15
- )
16
- }
17
-
18
- function Modal() {
19
- const { setModal, modal, modalResponse, setModalResponse } = useModal()
20
- const [open, setOpen] = useState(false)
21
-
22
- const handleClose = () => {
23
- setOpen(false)
24
- // Close after 100ms
25
- setTimeout(() => {
26
- setModal(null)
27
- }, 200)
28
- }
29
-
30
- const cancelButtonRef = useRef(null)
31
-
32
- useEffect(() => {
33
- if (!modal) {
34
- setModalResponse(null)
35
- } else {
36
- setOpen(true)
37
- }
38
- }, [modal])
39
-
40
- if (!modal) return null
41
-
42
- return (
43
- <Dialog open={open} onOpenChange={handleClose}>
44
- <DialogContent
45
- showCloseButton={false}
46
- onOpenAutoFocus={(e) => e.preventDefault()}
47
- onInteractOutside={(e) => e.preventDefault()}
48
- onPointerDownOutside={(e) => e.preventDefault()}
49
- className={classNames({
50
- 'bg-background w-full rounded-lg p-0 text-start': true,
51
- 'max-w-lg': modal?.size === 'sm' || modal?.size === undefined,
52
- 'max-w-2xl': modal?.size === 'md',
53
- 'max-w-4xl': modal?.size === 'lg',
54
- 'max-w-6xl': modal?.size === 'xl',
55
- })}
56
- >
57
- <DialogHeader>
58
- <DialogTitle
59
- className={`flex items-center rounded-t-lg text-xl leading-6 font-semibold ${modal?.titleColor} p-6 pt-5 pb-4 md:pe-20 ${modal?.headerColor}`}
60
- >
61
- <div>{modal?.title || ''}</div>
62
- <X
63
- className={`absolute end-5 size-6 cursor-pointer rounded bg-white text-gray-500 hover:opacity-90 md:block`}
64
- onClick={handleClose}
65
- ref={cancelButtonRef}
66
- />
67
- </DialogTitle>
68
- </DialogHeader>
69
- <div className='max-h-[calc(90vh-120px)] min-h-0 flex-1 overflow-y-auto'>
70
- <div className='flex flex-col gap-1'>
71
- <div className='w-full overflow-hidden'>
72
- <div className='flex w-full flex-col font-semibold'>
73
- <div className='text-foreground w-full'>
74
- <Suspense fallback={<ModalLoadingFallback />}>
75
- {modal?.body}
76
- </Suspense>
77
- </div>
78
- <div className='w-full'>
79
- {modalResponse && <div className={`w-full p-3`}>{modalResponse.message}</div>}
80
- </div>
81
- </div>
82
- </div>
83
- </div>
84
- </div>
85
- </DialogContent>
86
- </Dialog>
87
- )
88
-
89
- /*
90
- return (
91
- <Transition.Root show={modal !== null} as={Fragment}>
92
- <Dialog as='div' className='relative z-50' initialFocus={cancelButtonRef} onClose={handleClose}>
93
- <Transition.Child
94
- as={Fragment}
95
- enter='ease-out duration-300'
96
- enterFrom='opacity-0'
97
- enterTo='opacity-100'
98
- leave='ease-in duration-200'
99
- leaveFrom='opacity-100'
100
- leaveTo='opacity-0'
101
- >
102
- <div className='fixed inset-0 bg-gray-500/50 backdrop-blur-md transition-opacity' />
103
- </Transition.Child>
104
-
105
- <div className='fixed inset-0 z-10 overflow-y-auto'>
106
- <div className='flex min-h-full items-end justify-center p-4 text-start sm:items-start sm:p-0'>
107
- <Transition.Child
108
- as={Fragment}
109
- enter='ease-out duration-300'
110
- enterFrom='opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
111
- enterTo='opacity-100 translate-y-0 sm:scale-100'
112
- leave='ease-in duration-200'
113
- leaveFrom='opacity-100 translate-y-0 sm:scale-100'
114
- leaveTo='opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
115
- >
116
- <Dialog.Panel
117
- className={classNames({
118
- 'bg-background relative w-full rounded-lg text-start shadow-xl transition-all sm:my-8':
119
- true,
120
- 'max-w-lg': modal?.size === 'sm' || modal?.size === undefined,
121
- 'max-w-2xl': modal?.size === 'md',
122
- 'max-w-4xl': modal?.size === 'lg',
123
- 'max-w-6xl': modal?.size === 'xl',
124
- })}
125
- >
126
- <div className='bg-background rounded-lg'>
127
- {modal && (
128
- <div className='flex flex-col gap-1'>
129
- <div className='w-full overflow-hidden rounded'>
130
- <div
131
- className={`flex items-center rounded-t-lg text-xl leading-6 font-semibold ${modal.titleColor} p-6 pt-5 pb-4 md:pe-20 ${modal.headerColor}`}
132
- >
133
- <Dialog.Title as='h3' className='pe-5'>
134
- {modal.title}
135
- </Dialog.Title>
136
- <X
137
- className={`absolute ${
138
- modal.lang === 'ar' ? 'left-5' : 'right-5'
139
- } hidden h-7 w-7 cursor-pointer rounded bg-white text-gray-500 hover:opacity-90 md:block`}
140
- onClick={handleClose}
141
- ref={cancelButtonRef}
142
- />
143
- </div>
144
- <div className='flex w-full flex-col font-semibold'>
145
- <div className='text-foreground w-full'>{modal.body}</div>
146
- <div className='w-full'>
147
- {modalResponse && (
148
- <div className={`w-full p-3`}>{modalResponse.message}</div>
149
- )}
150
- </div>
151
- </div>
152
- </div>
153
- </div>
154
- )}
155
- </div>
156
- </Dialog.Panel>
157
- </Transition.Child>
158
- </div>
159
- </div>
160
- </Dialog>
161
- </Transition.Root>
162
- )
163
- */
164
- }
165
-
166
- export default Modal
1
+ 'use client'
2
+
3
+ import { Suspense, useEffect, useRef, useState } from 'react'
4
+ import { useModal } from '@/components/feedback/modal-context'
5
+ import classNames from 'classnames'
6
+ import { X, Loader2 } from 'lucide-react'
7
+
8
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/custom-dialog'
9
+
10
+ function ModalLoadingFallback() {
11
+ return (
12
+ <div className='flex min-h-[200px] items-center justify-center p-8'>
13
+ <Loader2 className='h-8 w-8 animate-spin text-muted-foreground' />
14
+ </div>
15
+ )
16
+ }
17
+
18
+ function Modal() {
19
+ const { setModal, modal, modalResponse, setModalResponse } = useModal()
20
+ const [open, setOpen] = useState(false)
21
+
22
+ const handleClose = () => {
23
+ setOpen(false)
24
+ // Close after 100ms
25
+ setTimeout(() => {
26
+ setModal(null)
27
+ }, 200)
28
+ }
29
+
30
+ const cancelButtonRef = useRef(null)
31
+
32
+ useEffect(() => {
33
+ if (!modal) {
34
+ setModalResponse(null)
35
+ } else {
36
+ setOpen(true)
37
+ }
38
+ }, [modal])
39
+
40
+ if (!modal) return null
41
+
42
+ return (
43
+ <Dialog open={open} onOpenChange={handleClose}>
44
+ <DialogContent
45
+ showCloseButton={false}
46
+ onOpenAutoFocus={(e) => e.preventDefault()}
47
+ onInteractOutside={(e) => e.preventDefault()}
48
+ onPointerDownOutside={(e) => e.preventDefault()}
49
+ className={classNames({
50
+ 'bg-background w-full rounded-lg p-0 text-start': true,
51
+ 'max-w-lg': modal?.size === 'sm' || modal?.size === undefined,
52
+ 'max-w-2xl': modal?.size === 'md',
53
+ 'max-w-4xl': modal?.size === 'lg',
54
+ 'max-w-6xl': modal?.size === 'xl',
55
+ })}
56
+ >
57
+ <DialogHeader>
58
+ <DialogTitle
59
+ className={`flex items-center rounded-t-lg text-xl leading-6 font-semibold ${modal?.titleColor} p-6 pt-5 pb-4 md:pe-20 ${modal?.headerColor}`}
60
+ >
61
+ <div>{modal?.title || ''}</div>
62
+ <X
63
+ className={`absolute end-5 size-6 cursor-pointer rounded bg-white text-gray-500 hover:opacity-90 md:block`}
64
+ onClick={handleClose}
65
+ ref={cancelButtonRef}
66
+ />
67
+ </DialogTitle>
68
+ </DialogHeader>
69
+ <div className='max-h-[calc(90vh-120px)] min-h-0 flex-1 overflow-y-auto'>
70
+ <div className='flex flex-col gap-1'>
71
+ <div className='w-full overflow-hidden'>
72
+ <div className='flex w-full flex-col font-semibold'>
73
+ <div className='text-foreground w-full'>
74
+ <Suspense fallback={<ModalLoadingFallback />}>
75
+ {modal?.body}
76
+ </Suspense>
77
+ </div>
78
+ <div className='w-full'>
79
+ {modalResponse && <div className={`w-full p-3`}>{modalResponse.message}</div>}
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </DialogContent>
86
+ </Dialog>
87
+ )
88
+
89
+ /*
90
+ return (
91
+ <Transition.Root show={modal !== null} as={Fragment}>
92
+ <Dialog as='div' className='relative z-50' initialFocus={cancelButtonRef} onClose={handleClose}>
93
+ <Transition.Child
94
+ as={Fragment}
95
+ enter='ease-out duration-300'
96
+ enterFrom='opacity-0'
97
+ enterTo='opacity-100'
98
+ leave='ease-in duration-200'
99
+ leaveFrom='opacity-100'
100
+ leaveTo='opacity-0'
101
+ >
102
+ <div className='fixed inset-0 bg-gray-500/50 backdrop-blur-md transition-opacity' />
103
+ </Transition.Child>
104
+
105
+ <div className='fixed inset-0 z-10 overflow-y-auto'>
106
+ <div className='flex min-h-full items-end justify-center p-4 text-start sm:items-start sm:p-0'>
107
+ <Transition.Child
108
+ as={Fragment}
109
+ enter='ease-out duration-300'
110
+ enterFrom='opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
111
+ enterTo='opacity-100 translate-y-0 sm:scale-100'
112
+ leave='ease-in duration-200'
113
+ leaveFrom='opacity-100 translate-y-0 sm:scale-100'
114
+ leaveTo='opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
115
+ >
116
+ <Dialog.Panel
117
+ className={classNames({
118
+ 'bg-background relative w-full rounded-lg text-start shadow-xl transition-all sm:my-8':
119
+ true,
120
+ 'max-w-lg': modal?.size === 'sm' || modal?.size === undefined,
121
+ 'max-w-2xl': modal?.size === 'md',
122
+ 'max-w-4xl': modal?.size === 'lg',
123
+ 'max-w-6xl': modal?.size === 'xl',
124
+ })}
125
+ >
126
+ <div className='bg-background rounded-lg'>
127
+ {modal && (
128
+ <div className='flex flex-col gap-1'>
129
+ <div className='w-full overflow-hidden rounded'>
130
+ <div
131
+ className={`flex items-center rounded-t-lg text-xl leading-6 font-semibold ${modal.titleColor} p-6 pt-5 pb-4 md:pe-20 ${modal.headerColor}`}
132
+ >
133
+ <Dialog.Title as='h3' className='pe-5'>
134
+ {modal.title}
135
+ </Dialog.Title>
136
+ <X
137
+ className={`absolute ${
138
+ modal.lang === 'ar' ? 'left-5' : 'right-5'
139
+ } hidden h-7 w-7 cursor-pointer rounded bg-white text-gray-500 hover:opacity-90 md:block`}
140
+ onClick={handleClose}
141
+ ref={cancelButtonRef}
142
+ />
143
+ </div>
144
+ <div className='flex w-full flex-col font-semibold'>
145
+ <div className='text-foreground w-full'>{modal.body}</div>
146
+ <div className='w-full'>
147
+ {modalResponse && (
148
+ <div className={`w-full p-3`}>{modalResponse.message}</div>
149
+ )}
150
+ </div>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ )}
155
+ </div>
156
+ </Dialog.Panel>
157
+ </Transition.Child>
158
+ </div>
159
+ </div>
160
+ </Dialog>
161
+ </Transition.Root>
162
+ )
163
+ */
164
+ }
165
+
166
+ export default Modal
@@ -1,48 +1,48 @@
1
- 'use client'
2
-
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
- )
48
- }
1
+ 'use client'
2
+
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
+ )
48
+ }
@@ -1,27 +1,27 @@
1
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
2
- export default function TooltipComponent({
3
- children,
4
- content,
5
- delayDuration = 200,
6
- }: {
7
- children: React.ReactNode
8
- content: React.ReactNode
9
- delayDuration?: number
10
- }) {
11
- if (!content) return children
12
- return (
13
- <TooltipProvider delayDuration={delayDuration}>
14
- <Tooltip>
15
- <TooltipTrigger
16
- onClick={(e) => {
17
- e.preventDefault()
18
- e.stopPropagation()
19
- }}
20
- >
21
- {children}
22
- </TooltipTrigger>
23
- <TooltipContent>{content}</TooltipContent>
24
- </Tooltip>
25
- </TooltipProvider>
26
- )
27
- }
1
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
2
+ export default function TooltipComponent({
3
+ children,
4
+ content,
5
+ delayDuration = 200,
6
+ }: {
7
+ children: React.ReactNode
8
+ content: React.ReactNode
9
+ delayDuration?: number
10
+ }) {
11
+ if (!content) return children
12
+ return (
13
+ <TooltipProvider delayDuration={delayDuration}>
14
+ <Tooltip>
15
+ <TooltipTrigger
16
+ onClick={(e) => {
17
+ e.preventDefault()
18
+ e.stopPropagation()
19
+ }}
20
+ >
21
+ {children}
22
+ </TooltipTrigger>
23
+ <TooltipContent>{content}</TooltipContent>
24
+ </Tooltip>
25
+ </TooltipProvider>
26
+ )
27
+ }
@@ -1,70 +1,70 @@
1
- import React from 'react'
2
- import classNames from 'classnames'
3
- import { Badge } from '@/components/ui/badge'
4
- import { FieldError } from 'react-hook-form'
5
- import { useI18n } from 'nextjs-cms/translations/client'
6
-
7
- export default function FormInputElement({
8
- label,
9
- required = false,
10
- readonly = false,
11
- classes = '',
12
- direction = 'row',
13
- value,
14
- children,
15
- validationError,
16
- }: {
17
- label: string
18
- required: boolean | string
19
- readonly?: boolean
20
- classes?: string
21
- direction?: 'row' | 'col'
22
- value?: any
23
- children: React.ReactNode
24
- validationError: FieldError | undefined
25
- }) {
26
- const t = useI18n()
27
- return (
28
- <div
29
- className={classNames({
30
- 'items-center py-2': true,
31
- 'flex flex-col': direction === 'col',
32
- 'items-center px-3 md-sidebar:grid md-sidebar:grid-cols-10': direction === 'row',
33
- classes: classes,
34
- })}
35
- >
36
- <label
37
- className={classNames({
38
- 'block pe-3 font-bold text-foreground': true,
39
- 'w-full text-start': direction === 'col',
40
- 'col-span-10 pb-1 md-sidebar:col-span-2 md-sidebar:pb-0 md-sidebar:text-end': direction === 'row',
41
- })}
42
- >
43
- {label} {['true', 1, true].includes(required) ? '*' : null}
44
- {readonly ? (
45
- <>
46
- {' '}
47
- <Badge variant={'primary'}>{t('readonly')}</Badge>
48
- </>
49
- ) : null}
50
- </label>
51
- <div
52
- className={classNames({
53
- 'col-span-8': direction === 'row',
54
- 'w-full': direction === 'col',
55
- })}
56
- >
57
- {readonly ? (
58
- <div className='w-full rounded bg-input p-3 text-foreground shadow-xs outline-0'>{value}</div>
59
- ) : (
60
- <>
61
- {children}
62
- {validationError ? (
63
- <div className='mt-1 text-sm text-red-500'>{validationError.message}</div>
64
- ) : null}
65
- </>
66
- )}
67
- </div>
68
- </div>
69
- )
70
- }
1
+ import React from 'react'
2
+ import classNames from 'classnames'
3
+ import { Badge } from '@/components/ui/badge'
4
+ import { FieldError } from 'react-hook-form'
5
+ import { useI18n } from 'nextjs-cms/translations/client'
6
+
7
+ export default function FormInputElement({
8
+ label,
9
+ required = false,
10
+ readonly = false,
11
+ classes = '',
12
+ direction = 'row',
13
+ value,
14
+ children,
15
+ validationError,
16
+ }: {
17
+ label: string
18
+ required: boolean | string
19
+ readonly?: boolean
20
+ classes?: string
21
+ direction?: 'row' | 'col'
22
+ value?: any
23
+ children: React.ReactNode
24
+ validationError: FieldError | undefined
25
+ }) {
26
+ const t = useI18n()
27
+ return (
28
+ <div
29
+ className={classNames({
30
+ 'items-center py-2': true,
31
+ 'flex flex-col': direction === 'col',
32
+ 'items-center px-3 md-sidebar:grid md-sidebar:grid-cols-10': direction === 'row',
33
+ classes: classes,
34
+ })}
35
+ >
36
+ <label
37
+ className={classNames({
38
+ 'block pe-3 font-bold text-foreground': true,
39
+ 'w-full text-start': direction === 'col',
40
+ 'col-span-10 pb-1 md-sidebar:col-span-2 md-sidebar:pb-0 md-sidebar:text-end': direction === 'row',
41
+ })}
42
+ >
43
+ {label} {['true', 1, true].includes(required) ? '*' : null}
44
+ {readonly ? (
45
+ <>
46
+ {' '}
47
+ <Badge variant={'primary'}>{t('readonly')}</Badge>
48
+ </>
49
+ ) : null}
50
+ </label>
51
+ <div
52
+ className={classNames({
53
+ 'col-span-8': direction === 'row',
54
+ 'w-full': direction === 'col',
55
+ })}
56
+ >
57
+ {readonly ? (
58
+ <div className='w-full rounded bg-input p-3 text-foreground shadow-xs outline-0'>{value}</div>
59
+ ) : (
60
+ <>
61
+ {children}
62
+ {validationError ? (
63
+ <div className='mt-1 text-sm text-red-500'>{validationError.message}</div>
64
+ ) : null}
65
+ </>
66
+ )}
67
+ </div>
68
+ </div>
69
+ )
70
+ }
@@ -8,4 +8,4 @@ export const revalidate = 0
8
8
 
9
9
  // @refresh reset
10
10
 
11
- export const configLastUpdated = 1778067978055
11
+ export const configLastUpdated = 1771768058991