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