create-nextjs-cms 0.9.4 → 0.9.6

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 (187) 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 +3 -3
  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)/layout.tsx +81 -81
  14. package/templates/default/app/(rootLayout)/(plugins)/[...slug]/page.tsx +40 -40
  15. package/templates/default/app/(rootLayout)/(plugins)/[...slug]/plugin-server-registry.ts +16 -16
  16. package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
  17. package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
  18. package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
  19. package/templates/default/app/(rootLayout)/dashboard/page.tsx +63 -63
  20. package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +20 -20
  21. package/templates/default/app/(rootLayout)/layout.tsx +81 -81
  22. package/templates/default/app/(rootLayout)/loading.tsx +10 -10
  23. package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
  24. package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
  25. package/templates/default/app/(rootLayout)/section/[section]/page.tsx +19 -19
  26. package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
  27. package/templates/default/app/_trpc/client.ts +3 -3
  28. package/templates/default/app/api/auth/csrf/route.ts +25 -25
  29. package/templates/default/app/api/auth/refresh/route.ts +10 -10
  30. package/templates/default/app/api/auth/route.ts +49 -49
  31. package/templates/default/app/api/auth/session/route.ts +20 -20
  32. package/templates/default/app/api/document/route.ts +165 -165
  33. package/templates/default/app/api/editor/photo/route.ts +49 -49
  34. package/templates/default/app/api/photo/route.ts +27 -27
  35. package/templates/default/app/api/submit/section/item/[slug]/route.ts +95 -95
  36. package/templates/default/app/api/submit/section/item/route.ts +56 -56
  37. package/templates/default/app/api/submit/section/simple/route.ts +86 -86
  38. package/templates/default/app/api/trpc/[trpc]/route.ts +33 -33
  39. package/templates/default/app/api/video/route.ts +174 -174
  40. package/templates/default/app/globals.css +228 -228
  41. package/templates/default/app/providers.tsx +152 -152
  42. package/templates/default/cms.config.ts +58 -57
  43. package/templates/default/components/AdminCard.tsx +166 -166
  44. package/templates/default/components/AdminEditPage.tsx +124 -124
  45. package/templates/default/components/AdminPrivilegeCard.tsx +185 -185
  46. package/templates/default/components/AdminsPage.tsx +43 -43
  47. package/templates/default/components/AnalyticsPage.tsx +144 -128
  48. package/templates/default/components/BarChartBox.tsx +42 -42
  49. package/templates/default/components/BrowsePage.tsx +106 -106
  50. package/templates/default/components/CategorizedSectionPage.tsx +31 -31
  51. package/templates/default/components/CategoryDeleteConfirmPage.tsx +130 -130
  52. package/templates/default/components/CategorySectionSelectInput.tsx +140 -140
  53. package/templates/default/components/ConditionalFields.tsx +49 -49
  54. package/templates/default/components/ContainerBox.tsx +24 -24
  55. package/templates/default/components/DashboardPageAlt.tsx +45 -45
  56. package/templates/default/components/DefaultNavItems.tsx +3 -3
  57. package/templates/default/components/Dropzone.tsx +154 -154
  58. package/templates/default/components/ErrorComponent.tsx +16 -16
  59. package/templates/default/components/GalleryPhoto.tsx +93 -93
  60. package/templates/default/components/InfoCard.tsx +93 -93
  61. package/templates/default/components/ItemEditPage.tsx +294 -294
  62. package/templates/default/components/Layout.tsx +84 -84
  63. package/templates/default/components/LoadingSpinners.tsx +67 -67
  64. package/templates/default/components/LocaleSwitcher.tsx +89 -89
  65. package/templates/default/components/LogPage.tsx +107 -107
  66. package/templates/default/components/Modal.tsx +166 -166
  67. package/templates/default/components/Navbar.tsx +258 -258
  68. package/templates/default/components/NewAdminForm.tsx +173 -173
  69. package/templates/default/components/NewPage.tsx +206 -206
  70. package/templates/default/components/NewVariantComponent.tsx +229 -229
  71. package/templates/default/components/PhotoGallery.tsx +35 -35
  72. package/templates/default/components/PieChartBox.tsx +101 -101
  73. package/templates/default/components/ProgressBar.tsx +48 -48
  74. package/templates/default/components/ProtectedDocument.tsx +44 -44
  75. package/templates/default/components/ProtectedImage.tsx +143 -143
  76. package/templates/default/components/ProtectedVideo.tsx +76 -76
  77. package/templates/default/components/SectionIcon.tsx +8 -8
  78. package/templates/default/components/SectionItemCard.tsx +144 -144
  79. package/templates/default/components/SectionItemStatusBadge.tsx +17 -17
  80. package/templates/default/components/SectionPage.tsx +205 -205
  81. package/templates/default/components/SelectBox.tsx +98 -98
  82. package/templates/default/components/SelectInputButtons.tsx +125 -125
  83. package/templates/default/components/SettingsPage.tsx +232 -232
  84. package/templates/default/components/Sidebar.tsx +204 -204
  85. package/templates/default/components/SidebarDropdownItem.tsx +83 -83
  86. package/templates/default/components/SidebarItem.tsx +24 -24
  87. package/templates/default/components/ThemeProvider.tsx +8 -8
  88. package/templates/default/components/TooltipComponent.tsx +27 -27
  89. package/templates/default/components/VariantCard.tsx +124 -124
  90. package/templates/default/components/VariantEditPage.tsx +230 -230
  91. package/templates/default/components/analytics/BounceRate.tsx +70 -70
  92. package/templates/default/components/analytics/LivePageViews.tsx +55 -55
  93. package/templates/default/components/analytics/LiveUsersCount.tsx +33 -33
  94. package/templates/default/components/analytics/MonthlyPageViews.tsx +42 -42
  95. package/templates/default/components/analytics/TopCountries.tsx +52 -52
  96. package/templates/default/components/analytics/TopDevices.tsx +46 -46
  97. package/templates/default/components/analytics/TopMediums.tsx +58 -58
  98. package/templates/default/components/analytics/TopSources.tsx +45 -45
  99. package/templates/default/components/analytics/TotalPageViews.tsx +41 -41
  100. package/templates/default/components/analytics/TotalSessions.tsx +41 -41
  101. package/templates/default/components/analytics/TotalUniqueUsers.tsx +41 -41
  102. package/templates/default/components/custom/RightHomeRoomVariantCard.tsx +138 -138
  103. package/templates/default/components/dndKit/Draggable.tsx +21 -21
  104. package/templates/default/components/dndKit/Droppable.tsx +20 -20
  105. package/templates/default/components/dndKit/SortableItem.tsx +18 -18
  106. package/templates/default/components/form/Form.tsx +370 -360
  107. package/templates/default/components/form/FormInputElement.tsx +70 -70
  108. package/templates/default/components/form/FormInputs.tsx +120 -111
  109. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  110. package/templates/default/components/form/helpers/util.ts +17 -17
  111. package/templates/default/components/form/inputs/CheckboxFormInput.tsx +46 -46
  112. package/templates/default/components/form/inputs/ColorFormInput.tsx +44 -44
  113. package/templates/default/components/form/inputs/DateFormInput.tsx +156 -156
  114. package/templates/default/components/form/inputs/DateRangeFormInput.tsx +153 -0
  115. package/templates/default/components/form/inputs/DocumentFormInput.tsx +222 -222
  116. package/templates/default/components/form/inputs/MapFormInput.tsx +140 -140
  117. package/templates/default/components/form/inputs/MultipleSelectFormInput.tsx +85 -85
  118. package/templates/default/components/form/inputs/NumberFormInput.tsx +43 -43
  119. package/templates/default/components/form/inputs/PasswordFormInput.tsx +47 -47
  120. package/templates/default/components/form/inputs/PhotoFormInput.tsx +275 -275
  121. package/templates/default/components/form/inputs/RichTextFormInput.tsx +138 -138
  122. package/templates/default/components/form/inputs/SelectFormInput.tsx +175 -175
  123. package/templates/default/components/form/inputs/SlugFormInput.tsx +131 -131
  124. package/templates/default/components/form/inputs/TagsFormInput.tsx +261 -260
  125. package/templates/default/components/form/inputs/TextFormInput.tsx +51 -51
  126. package/templates/default/components/form/inputs/TextareaFormInput.tsx +50 -50
  127. package/templates/default/components/form/inputs/VideoFormInput.tsx +118 -118
  128. package/templates/default/components/multi-select.tsx +1146 -1146
  129. package/templates/default/components/pagination/Pagination.tsx +36 -36
  130. package/templates/default/components/pagination/PaginationButtons.tsx +147 -147
  131. package/templates/default/components/theme-toggle.tsx +39 -39
  132. package/templates/default/components/ui/accordion.tsx +53 -53
  133. package/templates/default/components/ui/alert-dialog.tsx +157 -157
  134. package/templates/default/components/ui/alert.tsx +47 -47
  135. package/templates/default/components/ui/badge.tsx +38 -38
  136. package/templates/default/components/ui/button.tsx +62 -62
  137. package/templates/default/components/ui/calendar.tsx +166 -166
  138. package/templates/default/components/ui/card.tsx +43 -43
  139. package/templates/default/components/ui/checkbox.tsx +29 -29
  140. package/templates/default/components/ui/command.tsx +137 -137
  141. package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
  142. package/templates/default/components/ui/custom-dialog.tsx +123 -123
  143. package/templates/default/components/ui/dialog.tsx +123 -123
  144. package/templates/default/components/ui/direction.tsx +22 -22
  145. package/templates/default/components/ui/dropdown-menu.tsx +182 -182
  146. package/templates/default/components/ui/input-group.tsx +54 -54
  147. package/templates/default/components/ui/input.tsx +22 -22
  148. package/templates/default/components/ui/label.tsx +19 -19
  149. package/templates/default/components/ui/popover.tsx +42 -42
  150. package/templates/default/components/ui/progress.tsx +31 -31
  151. package/templates/default/components/ui/scroll-area.tsx +42 -42
  152. package/templates/default/components/ui/select.tsx +165 -165
  153. package/templates/default/components/ui/separator.tsx +28 -28
  154. package/templates/default/components/ui/sheet.tsx +103 -103
  155. package/templates/default/components/ui/spinner.tsx +16 -16
  156. package/templates/default/components/ui/switch.tsx +29 -29
  157. package/templates/default/components/ui/table.tsx +83 -83
  158. package/templates/default/components/ui/tabs.tsx +55 -55
  159. package/templates/default/components/ui/toast.tsx +113 -113
  160. package/templates/default/components/ui/toaster.tsx +35 -35
  161. package/templates/default/components/ui/tooltip.tsx +30 -30
  162. package/templates/default/components/ui/use-toast.ts +188 -188
  163. package/templates/default/components.json +21 -21
  164. package/templates/default/context/ModalProvider.tsx +53 -53
  165. package/templates/default/drizzle.config.ts +4 -4
  166. package/templates/default/env/env.js +130 -130
  167. package/templates/default/envConfig.ts +4 -4
  168. package/templates/default/hooks/useModal.ts +8 -8
  169. package/templates/default/lib/apiHelpers.ts +92 -92
  170. package/templates/default/lib/postinstall.js +14 -14
  171. package/templates/default/lib/utils.ts +6 -6
  172. package/templates/default/next-env.d.ts +6 -6
  173. package/templates/default/next.config.ts +23 -23
  174. package/templates/default/package.json +3 -3
  175. package/templates/default/postcss.config.mjs +6 -6
  176. package/templates/default/proxy.ts +32 -32
  177. package/templates/default/tsconfig.json +48 -48
  178. package/templates/default/app/(rootLayout)/dashboard-new/page.tsx +0 -7
  179. package/templates/default/components/DashboardNewPage.tsx +0 -253
  180. package/templates/default/components/DashboardPage.tsx +0 -188
  181. package/templates/default/components/EmailCard.tsx +0 -138
  182. package/templates/default/components/EmailPasswordForm.tsx +0 -85
  183. package/templates/default/components/EmailQuotaForm.tsx +0 -73
  184. package/templates/default/components/EmailsPage.tsx +0 -49
  185. package/templates/default/components/NewEmailForm.tsx +0 -132
  186. package/templates/default/components/form/DateRangeFormInput.tsx +0 -57
  187. package/templates/default/dynamic-schemas/schema.ts +0 -475
@@ -1,204 +1,204 @@
1
- import React from 'react'
2
- import classNames from 'classnames'
3
- import Link from 'next/link'
4
- import Image from 'next/image'
5
- import { SidebarProps } from 'nextjs-cms/core/types'
6
- import SidebarItem from '@/components/SidebarItem'
7
- import SidebarDropdownItem from '@/components/SidebarDropdownItem'
8
- import { ScrollArea } from '@/components/ui/scroll-area'
9
- import { useI18n } from 'nextjs-cms/translations/client'
10
- import ProtectedImage from '@/components/ProtectedImage'
11
- import { trpc } from '@/app/_trpc/client'
12
- import { useToast } from '@/components/ui/use-toast'
13
- import { logout, useSession } from 'nextjs-cms/auth/react'
14
- import { LogOut } from 'lucide-react'
15
-
16
- const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string; isRTL: boolean }) => {
17
- const t = useI18n()
18
- const session = useSession()
19
- const [navItems] = trpc.navigation.getSidebar.useSuspenseQuery()
20
- const { toast } = useToast()
21
- const handleLogout = async (e: React.MouseEvent<HTMLAnchorElement>) => {
22
- e.preventDefault()
23
- e.stopPropagation()
24
- try {
25
- await logout()
26
- } catch (error: any) {
27
- toast({
28
- variant: 'destructive',
29
- title: t('logoutError'),
30
- description: error.message,
31
- })
32
- }
33
- }
34
- return (
35
- <div
36
- className={classNames({
37
- 'fixed z-20 h-full bg-linear-to-br from-indigo-600 to-sky-500 text-zinc-50 dark:from-slate-950 dark:to-pink-950':
38
- true,
39
- 'transition-all duration-100 ease-in-out': true,
40
- 'w-[300px] md:w-[275px]': true,
41
- // LTR: sidebar on left, slides in from left
42
- 'left-0': !props.isRTL,
43
- 'md:translate-x-0': !props.isRTL,
44
- '-translate-x-full': !props.isRTL && !props.mobileSidebar,
45
- // RTL: sidebar on right, slides in from right
46
- 'right-0': props.isRTL,
47
- 'translate-x-full md:translate-x-0': props.isRTL && !props.mobileSidebar,
48
- // Mobile sidebar shown (both LTR and RTL)
49
- 'translate-x-0': props.mobileSidebar,
50
- })}
51
- >
52
- <div
53
- className={classNames({
54
- 'sticky inset-0 flex h-screen flex-col justify-between overflow-auto md:h-full': true,
55
- })}
56
- >
57
- {/* logo and collapse button */}
58
- <div
59
- className={classNames({
60
- 'sticky top-0 flex h-[65px] shrink-0 items-center bg-indigo-700 transition-none dark:bg-slate-900': true,
61
- 'justify-start gap-2 p-4': true,
62
- })}
63
- >
64
- <Image src={props.logoUrlPath} alt={t('logo') as string} width={32} height={32} />
65
- <span className='bg-transparent px-2 font-normal tracking-[0.1em] text-white/90 transition-all duration-150'>
66
- {props.logoText}
67
- </span>
68
- </div>
69
- <ScrollArea dir={props.isRTL ? 'rtl' : 'ltr'} type='always' className='grow'>
70
- <ul
71
- className={classNames({
72
- 'my-2 flex flex-col items-stretch gap-2': true,
73
- })}
74
- >
75
- {navItems && (
76
- <>
77
- {navItems.fixed_sections && navItems.fixed_sections.length > 0 && (
78
- <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
79
- <h2 className='my-2 text-start text-xs text-gray-300'>{t('main')}</h2>
80
- {navItems.fixed_sections.map((item, index) => {
81
- return (
82
- <SidebarItem
83
- closeSideBar={props.closeSideBar}
84
- key={index}
85
- item={item}
86
- />
87
- )
88
- })}
89
- </div>
90
- )}
91
-
92
- {navItems.cat_sections && navItems.cat_sections.length > 0 && (
93
- <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
94
- <h2 className='my-2 text-start text-xs text-gray-300'>{t('categorySections')}</h2>
95
- {navItems.cat_sections.map((item, index) => {
96
- return (
97
- <SidebarItem
98
- closeSideBar={props.closeSideBar}
99
- key={index}
100
- item={item}
101
- />
102
- )
103
- })}
104
- </div>
105
- )}
106
-
107
- {navItems.has_items_sections && navItems.has_items_sections.length > 0 && (
108
- <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
109
- <h2 className='my-2 text-start text-xs text-gray-300'>{t('sectionsWithItems')}</h2>
110
- <div className='flex flex-col gap-y-2'>
111
- {navItems.has_items_sections.map((item, index) => {
112
- return (
113
- <SidebarDropdownItem
114
- closeSideBar={props.closeSideBar}
115
- key={index}
116
- item={item}
117
- />
118
- )
119
- })}
120
- </div>
121
- </div>
122
- )}
123
- {navItems.simple_sections && navItems.simple_sections.length > 0 && (
124
- <div className='mx-3 flex flex-col border-b border-blue-900 py-2'>
125
- <h2 className='my-2 text-start text-xs text-gray-300'>{t('simpleSections')}</h2>
126
- {navItems.simple_sections.map((item, index) => {
127
- return (
128
- <SidebarItem
129
- closeSideBar={props.closeSideBar}
130
- key={index}
131
- item={item}
132
- />
133
- )
134
- })}
135
- </div>
136
- )}
137
- <div className='mx-3 flex flex-col py-2'>
138
- <h2 className='my-2 text-start text-xs text-gray-300'>{t('settings')}</h2>
139
- <SidebarItem
140
- closeSideBar={props.closeSideBar}
141
- key={101}
142
- item={{
143
- path: '/settings',
144
- title: t('accountSettings'),
145
- icon: 'cog'
146
- }}
147
- />
148
- <Link
149
- href='#'
150
- onClick={handleLogout}
151
- className={classNames({
152
- 'flex flex-row gap-1 items-center rounded-lg hover:text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
153
- 'transition-colors duration-100': false, //animation
154
- 'gap-4 p-2 text-start': true,
155
- })}
156
- >
157
- <LogOut className='size-4' />
158
- <span>{t('logout')}</span>
159
- </Link>
160
- </div>
161
- </>
162
- )}
163
- </ul>
164
- </ScrollArea>
165
- <div
166
- className={classNames({
167
- 'grid place-content-stretch bg-indigo-700 p-2 dark:bg-slate-800': true,
168
- })}
169
- >
170
- <div className='flex h-12 items-center gap-4'>
171
- {session?.data?.user.image ? (
172
- <ProtectedImage
173
- section={'admins'}
174
- photo={session.data.user.image}
175
- isThumb={true}
176
- alt={session?.data?.user.name}
177
- width={40}
178
- height={40}
179
- // fill={true}
180
- className='ring-foreground rounded-full ring-3'
181
- />
182
- ) : (
183
- <Image
184
- src='/blank_avatar.png'
185
- height={36}
186
- width={36}
187
- alt={t('profileImage') as string}
188
- className='rounded-full ring-2 ring-amber-300 ring-inset'
189
- />
190
- )}
191
-
192
- <div className='flex flex-col text-start'>
193
- <span className='my-0 text-indigo-50'>{session?.data?.user.name}</span>
194
- <Link href='/settings' className='text-sm text-indigo-200'>
195
- {t('settings')}
196
- </Link>
197
- </div>
198
- </div>
199
- </div>
200
- </div>
201
- </div>
202
- )
203
- }
204
- export default Sidebar
1
+ import React from 'react'
2
+ import classNames from 'classnames'
3
+ import Link from 'next/link'
4
+ import Image from 'next/image'
5
+ import { SidebarProps } from 'nextjs-cms/core/types'
6
+ import SidebarItem from '@/components/SidebarItem'
7
+ import SidebarDropdownItem from '@/components/SidebarDropdownItem'
8
+ import { ScrollArea } from '@/components/ui/scroll-area'
9
+ import { useI18n } from 'nextjs-cms/translations/client'
10
+ import ProtectedImage from '@/components/ProtectedImage'
11
+ import { trpc } from '@/app/_trpc/client'
12
+ import { useToast } from '@/components/ui/use-toast'
13
+ import { logout, useSession } from 'nextjs-cms/auth/react'
14
+ import { LogOut } from 'lucide-react'
15
+
16
+ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string; isRTL: boolean }) => {
17
+ const t = useI18n()
18
+ const session = useSession()
19
+ const [navItems] = trpc.navigation.getSidebar.useSuspenseQuery()
20
+ const { toast } = useToast()
21
+ const handleLogout = async (e: React.MouseEvent<HTMLAnchorElement>) => {
22
+ e.preventDefault()
23
+ e.stopPropagation()
24
+ try {
25
+ await logout()
26
+ } catch (error: any) {
27
+ toast({
28
+ variant: 'destructive',
29
+ title: t('logoutError'),
30
+ description: error.message,
31
+ })
32
+ }
33
+ }
34
+ return (
35
+ <div
36
+ className={classNames({
37
+ 'fixed z-20 h-full bg-linear-to-br from-indigo-600 to-sky-500 text-zinc-50 dark:from-slate-950 dark:to-pink-950':
38
+ true,
39
+ 'transition-all duration-100 ease-in-out': true,
40
+ 'w-[300px] md:w-[275px]': true,
41
+ // LTR: sidebar on left, slides in from left
42
+ 'left-0': !props.isRTL,
43
+ 'md:translate-x-0': !props.isRTL,
44
+ '-translate-x-full': !props.isRTL && !props.mobileSidebar,
45
+ // RTL: sidebar on right, slides in from right
46
+ 'right-0': props.isRTL,
47
+ 'translate-x-full md:translate-x-0': props.isRTL && !props.mobileSidebar,
48
+ // Mobile sidebar shown (both LTR and RTL)
49
+ 'translate-x-0': props.mobileSidebar,
50
+ })}
51
+ >
52
+ <div
53
+ className={classNames({
54
+ 'sticky inset-0 flex h-screen flex-col justify-between overflow-auto md:h-full': true,
55
+ })}
56
+ >
57
+ {/* logo and collapse button */}
58
+ <div
59
+ className={classNames({
60
+ 'sticky top-0 flex h-[65px] shrink-0 items-center bg-indigo-700 transition-none dark:bg-slate-900': true,
61
+ 'justify-start gap-2 p-4': true,
62
+ })}
63
+ >
64
+ <Image src={props.logoUrlPath} alt={t('logo') as string} width={32} height={32} />
65
+ <span className='bg-transparent px-2 font-normal tracking-[0.1em] text-white/90 transition-all duration-150'>
66
+ {props.logoText}
67
+ </span>
68
+ </div>
69
+ <ScrollArea dir={props.isRTL ? 'rtl' : 'ltr'} type='always' className='grow'>
70
+ <ul
71
+ className={classNames({
72
+ 'my-2 flex flex-col items-stretch gap-2': true,
73
+ })}
74
+ >
75
+ {navItems && (
76
+ <>
77
+ {navItems.fixed_sections && navItems.fixed_sections.length > 0 && (
78
+ <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
79
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('main')}</h2>
80
+ {navItems.fixed_sections.map((item, index) => {
81
+ return (
82
+ <SidebarItem
83
+ closeSideBar={props.closeSideBar}
84
+ key={index}
85
+ item={item}
86
+ />
87
+ )
88
+ })}
89
+ </div>
90
+ )}
91
+
92
+ {navItems.cat_sections && navItems.cat_sections.length > 0 && (
93
+ <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
94
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('categorySections')}</h2>
95
+ {navItems.cat_sections.map((item, index) => {
96
+ return (
97
+ <SidebarItem
98
+ closeSideBar={props.closeSideBar}
99
+ key={index}
100
+ item={item}
101
+ />
102
+ )
103
+ })}
104
+ </div>
105
+ )}
106
+
107
+ {navItems.has_items_sections && navItems.has_items_sections.length > 0 && (
108
+ <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
109
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('sectionsWithItems')}</h2>
110
+ <div className='flex flex-col gap-y-2'>
111
+ {navItems.has_items_sections.map((item, index) => {
112
+ return (
113
+ <SidebarDropdownItem
114
+ closeSideBar={props.closeSideBar}
115
+ key={index}
116
+ item={item}
117
+ />
118
+ )
119
+ })}
120
+ </div>
121
+ </div>
122
+ )}
123
+ {navItems.simple_sections && navItems.simple_sections.length > 0 && (
124
+ <div className='mx-3 flex flex-col border-b border-blue-900 py-2'>
125
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('simpleSections')}</h2>
126
+ {navItems.simple_sections.map((item, index) => {
127
+ return (
128
+ <SidebarItem
129
+ closeSideBar={props.closeSideBar}
130
+ key={index}
131
+ item={item}
132
+ />
133
+ )
134
+ })}
135
+ </div>
136
+ )}
137
+ <div className='mx-3 flex flex-col py-2'>
138
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('settings')}</h2>
139
+ <SidebarItem
140
+ closeSideBar={props.closeSideBar}
141
+ key={101}
142
+ item={{
143
+ path: '/settings',
144
+ title: t('accountSettings'),
145
+ icon: 'cog'
146
+ }}
147
+ />
148
+ <Link
149
+ href='#'
150
+ onClick={handleLogout}
151
+ className={classNames({
152
+ 'flex flex-row gap-1 items-center rounded-lg hover:text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
153
+ 'transition-colors duration-100': false, //animation
154
+ 'gap-4 p-2 text-start': true,
155
+ })}
156
+ >
157
+ <LogOut className='size-4' />
158
+ <span>{t('logout')}</span>
159
+ </Link>
160
+ </div>
161
+ </>
162
+ )}
163
+ </ul>
164
+ </ScrollArea>
165
+ <div
166
+ className={classNames({
167
+ 'grid place-content-stretch bg-indigo-700 p-2 dark:bg-slate-800': true,
168
+ })}
169
+ >
170
+ <div className='flex h-12 items-center gap-4'>
171
+ {session?.data?.user.image ? (
172
+ <ProtectedImage
173
+ section={'admins'}
174
+ photo={session.data.user.image}
175
+ isThumb={true}
176
+ alt={session?.data?.user.name}
177
+ width={40}
178
+ height={40}
179
+ // fill={true}
180
+ className='ring-foreground rounded-full ring-3'
181
+ />
182
+ ) : (
183
+ <Image
184
+ src='/blank_avatar.png'
185
+ height={36}
186
+ width={36}
187
+ alt={t('profileImage') as string}
188
+ className='rounded-full ring-2 ring-amber-300 ring-inset'
189
+ />
190
+ )}
191
+
192
+ <div className='flex flex-col text-start'>
193
+ <span className='my-0 text-indigo-50'>{session?.data?.user.name}</span>
194
+ <Link href='/settings' className='text-sm text-indigo-200'>
195
+ {t('settings')}
196
+ </Link>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </div>
202
+ )
203
+ }
204
+ export default Sidebar
@@ -1,83 +1,83 @@
1
- import Link from 'next/link'
2
- import classNames from 'classnames'
3
- import { useState } from 'react'
4
- import { SidebarItemProps } from 'nextjs-cms/core/types'
5
- import { useAutoAnimate } from '@formkit/auto-animate/react'
6
- import { ChevronDownIcon, ChevronUpIcon, FolderIcon, PlusIcon } from 'lucide-react'
7
- import { useI18n } from 'nextjs-cms/translations/client'
8
- import SectionIcon from '@/components/SectionIcon'
9
-
10
- export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemProps) {
11
- const t = useI18n()
12
- const [parent] = useAutoAnimate()
13
- const [open, setOpen] = useState(false)
14
- return (
15
- <div ref={parent}>
16
- <div
17
- className={classNames({
18
- 'flex cursor-pointer text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
19
- 'transition-colors duration-100': false, //animation
20
- 'gap-4 rounded-md p-2': true,
21
- 'rounded-b-none bg-indigo-700 dark:bg-emerald-600': open,
22
- })}
23
- onClick={() => setOpen((prev) => !prev)}
24
- >
25
- <li className='relative flex w-full items-center justify-between gap-2'>
26
- <span className='flex items-center gap-2 text-start'>
27
- {item.icon && <SectionIcon name={item.icon} className='size-4' />}
28
- <span>{item.title}</span>
29
- </span>
30
- <span>
31
- {open ? (
32
- <ChevronUpIcon className='h-5 w-5' />
33
- ) : (
34
- <ChevronDownIcon className='h-5 w-5' />
35
- )}
36
- </span>
37
- </li>
38
- </div>
39
- {open && (
40
- <div
41
- className={classNames({
42
- 'rounded border border-t-0 border-indigo-700/50 text-white dark:border-emerald-600/50': true, //colors
43
- 'transition-colors duration-100': false, //animation
44
- 'flex flex-col items-stretch rounded-md rounded-t-none py-2': true,
45
- })}
46
- >
47
- <Link
48
- onClick={closeSideBar}
49
- href={`/new${item.path}`}
50
- className={classNames({
51
- 'flex rounded text-white hover:underline': true, //colors
52
- 'transition-colors duration-100': false, //animation
53
- 'mx-3 gap-4 p-2': true,
54
- })}
55
- >
56
- <li className='flex flex-row items-center gap-1'>
57
- <span>
58
- <PlusIcon className='size-4' />
59
- </span>
60
- <span>{t('new')}</span>
61
- </li>
62
- </Link>
63
- <Link
64
- onClick={closeSideBar}
65
- href={`/browse${item.path}`}
66
- className={classNames({
67
- 'flex rounded text-white hover:underline': true, //colors
68
- 'transition-colors duration-100': false, //animation
69
- 'mx-3 gap-4 p-2': true,
70
- })}
71
- >
72
- <li className='flex flex-row items-center gap-1'>
73
- <span>
74
- <FolderIcon className='size-4' />
75
- </span>
76
- <span>{t('browse')}</span>
77
- </li>
78
- </Link>
79
- </div>
80
- )}
81
- </div>
82
- )
83
- }
1
+ import Link from 'next/link'
2
+ import classNames from 'classnames'
3
+ import { useState } from 'react'
4
+ import { SidebarItemProps } from 'nextjs-cms/core/types'
5
+ import { useAutoAnimate } from '@formkit/auto-animate/react'
6
+ import { ChevronDownIcon, ChevronUpIcon, FolderIcon, PlusIcon } from 'lucide-react'
7
+ import { useI18n } from 'nextjs-cms/translations/client'
8
+ import SectionIcon from '@/components/SectionIcon'
9
+
10
+ export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemProps) {
11
+ const t = useI18n()
12
+ const [parent] = useAutoAnimate()
13
+ const [open, setOpen] = useState(false)
14
+ return (
15
+ <div ref={parent}>
16
+ <div
17
+ className={classNames({
18
+ 'flex cursor-pointer text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
19
+ 'transition-colors duration-100': false, //animation
20
+ 'gap-4 rounded-md p-2': true,
21
+ 'rounded-b-none bg-indigo-700 dark:bg-emerald-600': open,
22
+ })}
23
+ onClick={() => setOpen((prev) => !prev)}
24
+ >
25
+ <li className='relative flex w-full items-center justify-between gap-2'>
26
+ <span className='flex items-center gap-2 text-start'>
27
+ {item.icon && <SectionIcon name={item.icon} className='size-4' />}
28
+ <span>{item.title}</span>
29
+ </span>
30
+ <span>
31
+ {open ? (
32
+ <ChevronUpIcon className='h-5 w-5' />
33
+ ) : (
34
+ <ChevronDownIcon className='h-5 w-5' />
35
+ )}
36
+ </span>
37
+ </li>
38
+ </div>
39
+ {open && (
40
+ <div
41
+ className={classNames({
42
+ 'rounded border border-t-0 border-indigo-700/50 text-white dark:border-emerald-600/50': true, //colors
43
+ 'transition-colors duration-100': false, //animation
44
+ 'flex flex-col items-stretch rounded-md rounded-t-none py-2': true,
45
+ })}
46
+ >
47
+ <Link
48
+ onClick={closeSideBar}
49
+ href={`/new${item.path}`}
50
+ className={classNames({
51
+ 'flex rounded text-white hover:underline': true, //colors
52
+ 'transition-colors duration-100': false, //animation
53
+ 'mx-3 gap-4 p-2': true,
54
+ })}
55
+ >
56
+ <li className='flex flex-row items-center gap-1'>
57
+ <span>
58
+ <PlusIcon className='size-4' />
59
+ </span>
60
+ <span>{t('new')}</span>
61
+ </li>
62
+ </Link>
63
+ <Link
64
+ onClick={closeSideBar}
65
+ href={`/browse${item.path}`}
66
+ className={classNames({
67
+ 'flex rounded text-white hover:underline': true, //colors
68
+ 'transition-colors duration-100': false, //animation
69
+ 'mx-3 gap-4 p-2': true,
70
+ })}
71
+ >
72
+ <li className='flex flex-row items-center gap-1'>
73
+ <span>
74
+ <FolderIcon className='size-4' />
75
+ </span>
76
+ <span>{t('browse')}</span>
77
+ </li>
78
+ </Link>
79
+ </div>
80
+ )}
81
+ </div>
82
+ )
83
+ }
@@ -1,24 +1,24 @@
1
- import Link from 'next/link'
2
- import classNames from 'classnames'
3
- import { SidebarItemProps } from 'nextjs-cms/core/types'
4
- import SectionIcon from '@/components/SectionIcon'
5
-
6
- export default function SidebarItem({ item, closeSideBar }: SidebarItemProps) {
7
- return (
8
- <Link
9
- onClick={closeSideBar}
10
- href={item.path}
11
- className={classNames({
12
- 'rounded-lg text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
13
- 'transition-colors duration-100': false, //animation
14
- 'gap-4 p-2': true,
15
- 'text-start': true, // RTL support
16
- })}
17
- >
18
- <span className='flex items-center gap-2'>
19
- {item.icon && <SectionIcon name={item.icon} className='size-4' />}
20
- <span>{item.title}</span>
21
- </span>
22
- </Link>
23
- )
24
- }
1
+ import Link from 'next/link'
2
+ import classNames from 'classnames'
3
+ import { SidebarItemProps } from 'nextjs-cms/core/types'
4
+ import SectionIcon from '@/components/SectionIcon'
5
+
6
+ export default function SidebarItem({ item, closeSideBar }: SidebarItemProps) {
7
+ return (
8
+ <Link
9
+ onClick={closeSideBar}
10
+ href={item.path}
11
+ className={classNames({
12
+ 'rounded-lg text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
13
+ 'transition-colors duration-100': false, //animation
14
+ 'gap-4 p-2': true,
15
+ 'text-start': true, // RTL support
16
+ })}
17
+ >
18
+ <span className='flex items-center gap-2'>
19
+ {item.icon && <SectionIcon name={item.icon} className='size-4' />}
20
+ <span>{item.title}</span>
21
+ </span>
22
+ </Link>
23
+ )
24
+ }