create-nextjs-cms 0.9.22 → 0.9.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/templates/default/app/(auth)/auth/login/LoginPage.tsx +2 -2
- package/templates/default/app/(auth)/layout.tsx +1 -1
- package/templates/default/app/(rootLayout)/(plugins)/[...slug]/page.tsx +47 -40
- package/templates/default/app/(rootLayout)/(plugins)/[...slug]/plugin-server-registry.ts +16 -16
- package/templates/default/app/(rootLayout)/admins/page.tsx +2 -2
- package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +2 -2
- package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +2 -2
- package/templates/default/app/(rootLayout)/dashboard/page.tsx +10 -3
- package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +2 -2
- package/templates/default/app/(rootLayout)/layout.tsx +3 -3
- package/templates/default/app/(rootLayout)/loading.tsx +1 -1
- package/templates/default/app/(rootLayout)/log/page.tsx +1 -1
- package/templates/default/app/(rootLayout)/new/[section]/page.tsx +2 -2
- package/templates/default/app/(rootLayout)/section/[section]/page.tsx +2 -2
- package/templates/default/app/(rootLayout)/settings/page.tsx +2 -2
- package/templates/default/app/_trpc/client.tsx +6 -0
- package/templates/default/app/_trpc/server.ts +9 -0
- package/templates/default/app/_trpc/types.ts +6 -0
- package/templates/default/app/api/document/route.ts +1 -1
- package/templates/default/app/api/photo/route.ts +1 -1
- package/templates/default/app/api/trpc/[trpc]/route.ts +3 -33
- package/templates/default/app/api/video/route.ts +1 -1
- package/templates/default/app/providers.tsx +20 -152
- package/templates/default/cms.config.ts +4 -2
- package/templates/default/components/{AdminCard.tsx → admin/admin-card.tsx} +4 -4
- package/templates/default/components/{AdminEditPage.tsx → admin/admin-edit-page.tsx} +3 -3
- package/templates/default/components/{AdminPrivilegeCard.tsx → admin/admin-privilege-card.tsx} +1 -1
- package/templates/default/components/{NewAdminForm.tsx → admin/new-admin-form.tsx} +4 -4
- package/templates/default/components/{ContainerBox.tsx → container-box.tsx} +1 -1
- package/templates/default/components/{ErrorComponent.tsx → feedback/error-component.tsx} +1 -1
- package/templates/default/{context/ModalProvider.tsx → components/feedback/modal-context.tsx} +56 -53
- package/templates/default/components/{Modal.tsx → feedback/modal.tsx} +1 -1
- package/templates/default/components/form/{FormInputs.tsx → form-inputs.tsx} +17 -17
- package/templates/default/components/form/{Form.tsx → form.tsx} +17 -11
- package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
- package/templates/default/components/form/inputs/{CheckboxFormInput.tsx → checkbox-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{ColorFormInput.tsx → color-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{DateFormInput.tsx → date-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{DateRangeFormInput.tsx → date-range-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{DocumentFormInput.tsx → document-form-input.tsx} +3 -3
- package/templates/default/components/form/inputs/{MapFormInput.tsx → map-form-input.tsx} +5 -4
- package/templates/default/components/form/inputs/{MultipleSelectFormInput.tsx → multiple-select-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{NumberFormInput.tsx → number-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{PasswordFormInput.tsx → password-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{PhotoFormInput.tsx → photo-form-input.tsx} +3 -3
- package/templates/default/components/form/inputs/{RichTextFormInput.tsx → rich-text-form-input.tsx} +3 -3
- package/templates/default/components/form/inputs/{SelectFormInput.tsx → select-form-input.tsx} +4 -4
- package/templates/default/components/form/inputs/{SlugFormInput.tsx → slug-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{TagsFormInput.tsx → tags-form-input.tsx} +1 -1
- package/templates/default/components/form/inputs/{TextFormInput.tsx → text-form-input.tsx} +3 -3
- package/templates/default/components/form/inputs/{TextareaFormInput.tsx → textarea-form-input.tsx} +2 -2
- package/templates/default/components/form/inputs/{VideoFormInput.tsx → video-form-input.tsx} +3 -3
- package/templates/default/components/{Layout.tsx → layout/layout.tsx} +4 -4
- package/templates/default/components/{Navbar.tsx → layout/navbar.tsx} +2 -2
- package/templates/default/components/{SidebarDropdownItem.tsx → layout/sidebar-dropdown-item.tsx} +1 -1
- package/templates/default/components/{SidebarItem.tsx → layout/sidebar-item.tsx} +1 -1
- package/templates/default/components/layout/sidebar-plugin-group.tsx +63 -0
- package/templates/default/components/{Sidebar.tsx → layout/sidebar.tsx} +28 -3
- package/templates/default/components/{LocaleSwitcher.tsx → locale/locale-switcher.tsx} +2 -2
- package/templates/default/components/{Dropzone.tsx → media/dropzone.tsx} +1 -1
- package/templates/default/components/{GalleryPhoto.tsx → media/gallery-photo.tsx} +2 -2
- package/templates/default/components/{PhotoGallery.tsx → media/photo-gallery.tsx} +2 -2
- package/templates/default/components/{ProtectedImage.tsx → media/protected-image.tsx} +1 -1
- package/templates/default/components/multi-select.tsx +8 -4
- package/templates/default/components/{AdminsPage.tsx → pages/admins-page.tsx} +4 -4
- package/templates/default/components/{BrowsePage.tsx → pages/browse-page.tsx} +7 -7
- package/templates/default/components/{CategorizedSectionPage.tsx → pages/categorized-section-page.tsx} +2 -2
- package/templates/default/components/{ItemEditPage.tsx → pages/item-edit-page.tsx} +8 -34
- package/templates/default/components/{LogPage.tsx → pages/log-page.tsx} +1 -1
- package/templates/default/components/{NewPage.tsx → pages/new-page.tsx} +28 -51
- package/templates/default/components/{SectionPage.tsx → pages/section-page.tsx} +7 -7
- package/templates/default/components/{SettingsPage.tsx → pages/settings-page.tsx} +4 -4
- package/templates/default/components/pagination/{Pagination.tsx → pagination.tsx} +1 -1
- package/templates/default/components/{CategoryDeleteConfirmPage.tsx → sections/category-delete-confirm-page.tsx} +4 -4
- package/templates/default/components/{CategorySectionSelectInput.tsx → sections/category-section-select-input.tsx} +5 -5
- package/templates/default/components/{ConditionalFields.tsx → sections/conditional-fields.tsx} +1 -1
- package/templates/default/components/{SectionItemCard.tsx → sections/section-item-card.tsx} +4 -4
- package/templates/default/components/{SelectInputButtons.tsx → sections/select-input-buttons.tsx} +4 -4
- package/templates/default/dynamic-schemas/schema.ts +44 -2
- package/templates/default/env/env.ts +42 -0
- package/templates/default/next.config.ts +1 -0
- package/templates/default/package.json +2 -1
- package/templates/default/app/_trpc/client.ts +0 -3
- package/templates/default/components/AnalyticsPage.tsx +0 -144
- package/templates/default/components/BarChartBox.tsx +0 -42
- package/templates/default/components/NewVariantComponent.tsx +0 -229
- package/templates/default/components/PieChartBox.tsx +0 -101
- package/templates/default/components/VariantCard.tsx +0 -124
- package/templates/default/components/VariantEditPage.tsx +0 -230
- package/templates/default/components/analytics/BounceRate.tsx +0 -70
- package/templates/default/components/analytics/LivePageViews.tsx +0 -55
- package/templates/default/components/analytics/LiveUsersCount.tsx +0 -33
- package/templates/default/components/analytics/MonthlyPageViews.tsx +0 -42
- package/templates/default/components/analytics/TopCountries.tsx +0 -52
- package/templates/default/components/analytics/TopDevices.tsx +0 -46
- package/templates/default/components/analytics/TopMediums.tsx +0 -58
- package/templates/default/components/analytics/TopSources.tsx +0 -45
- package/templates/default/components/analytics/TotalPageViews.tsx +0 -41
- package/templates/default/components/analytics/TotalSessions.tsx +0 -41
- package/templates/default/components/analytics/TotalUniqueUsers.tsx +0 -41
- package/templates/default/components/custom/RightHomeRoomVariantCard.tsx +0 -138
- package/templates/default/env/env.js +0 -130
- package/templates/default/hooks/useModal.ts +0 -8
- package/templates/default/lib/apiHelpers.ts +0 -92
- /package/templates/default/components/{dndKit/Draggable.tsx → dnd-kit/draggable.tsx} +0 -0
- /package/templates/default/components/{dndKit/Droppable.tsx → dnd-kit/droppable.tsx} +0 -0
- /package/templates/default/components/{dndKit/SortableItem.tsx → dnd-kit/sortable-item.tsx} +0 -0
- /package/templates/default/components/{InfoCard.tsx → feedback/info-card.tsx} +0 -0
- /package/templates/default/components/{LoadingSpinners.tsx → feedback/loading-spinners.tsx} +0 -0
- /package/templates/default/components/{ProgressBar.tsx → feedback/progress-bar.tsx} +0 -0
- /package/templates/default/components/{TooltipComponent.tsx → feedback/tooltip-component.tsx} +0 -0
- /package/templates/default/components/form/{ContentLocaleContext.tsx → content-locale-context.tsx} +0 -0
- /package/templates/default/components/form/{FormInputElement.tsx → form-input-element.tsx} +0 -0
- /package/templates/default/components/{language-dropdown.tsx → i18n/language-dropdown.tsx} +0 -0
- /package/templates/default/components/{language-picker.tsx → i18n/language-picker.tsx} +0 -0
- /package/templates/default/components/{login-language-dropdown.tsx → i18n/login-language-dropdown.tsx} +0 -0
- /package/templates/default/components/{DefaultNavItems.tsx → layout/default-nav-items.tsx} +0 -0
- /package/templates/default/components/{ThemeProvider.tsx → layout/theme-provider.tsx} +0 -0
- /package/templates/default/components/{theme-toggle.tsx → layout/theme-toggle.tsx} +0 -0
- /package/templates/default/components/{ProtectedDocument.tsx → media/protected-document.tsx} +0 -0
- /package/templates/default/components/{ProtectedVideo.tsx → media/protected-video.tsx} +0 -0
- /package/templates/default/components/{DashboardPageAlt.tsx → pages/dashboard-page-alt.tsx} +0 -0
- /package/templates/default/components/pagination/{PaginationButtons.tsx → pagination-buttons.tsx} +0 -0
- /package/templates/default/components/{SectionIcon.tsx → sections/section-icon.tsx} +0 -0
- /package/templates/default/components/{SectionItemStatusBadge.tsx → sections/section-item-status-badge.tsx} +0 -0
- /package/templates/default/components/{SelectBox.tsx → select-box.tsx} +0 -0
|
@@ -3,11 +3,12 @@ import classNames from 'classnames'
|
|
|
3
3
|
import Link from 'next/link'
|
|
4
4
|
import Image from 'next/image'
|
|
5
5
|
import { SidebarProps } from 'nextjs-cms/core/types'
|
|
6
|
-
import SidebarItem from '@/components/
|
|
7
|
-
import SidebarDropdownItem from '@/components/
|
|
6
|
+
import SidebarItem from '@/components/layout/sidebar-item'
|
|
7
|
+
import SidebarDropdownItem from '@/components/layout/sidebar-dropdown-item'
|
|
8
|
+
import SidebarPluginGroup from '@/components/layout/sidebar-plugin-group'
|
|
8
9
|
import { ScrollArea } from '@/components/ui/scroll-area'
|
|
9
10
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
10
|
-
import ProtectedImage from '@/components/
|
|
11
|
+
import ProtectedImage from '@/components/media/protected-image'
|
|
11
12
|
import { trpc } from '@/app/_trpc/client'
|
|
12
13
|
import { useToast } from '@/components/ui/use-toast'
|
|
13
14
|
import { logout, useSession } from 'nextjs-cms/auth/react'
|
|
@@ -89,6 +90,30 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string;
|
|
|
89
90
|
</div>
|
|
90
91
|
)}
|
|
91
92
|
|
|
93
|
+
{navItems.plugin_sections && navItems.plugin_sections.length > 0 && (
|
|
94
|
+
<div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
|
|
95
|
+
<h2 className='my-2 text-start text-xs text-gray-300'>{t('plugins')}</h2>
|
|
96
|
+
{navItems.plugin_sections.map((item, index) => {
|
|
97
|
+
if (item.kind === 'group') {
|
|
98
|
+
return (
|
|
99
|
+
<SidebarPluginGroup
|
|
100
|
+
closeSideBar={props.closeSideBar}
|
|
101
|
+
key={index}
|
|
102
|
+
group={item}
|
|
103
|
+
/>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
return (
|
|
107
|
+
<SidebarItem
|
|
108
|
+
closeSideBar={props.closeSideBar}
|
|
109
|
+
key={index}
|
|
110
|
+
item={item}
|
|
111
|
+
/>
|
|
112
|
+
)
|
|
113
|
+
})}
|
|
114
|
+
</div>
|
|
115
|
+
)}
|
|
116
|
+
|
|
92
117
|
{navItems.cat_sections && navItems.cat_sections.length > 0 && (
|
|
93
118
|
<div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
|
|
94
119
|
<h2 className='my-2 text-start text-xs text-gray-300'>{t('categorySections')}</h2>
|
|
@@ -5,8 +5,8 @@ import { cn } from '@/lib/utils'
|
|
|
5
5
|
import { Check } from 'lucide-react'
|
|
6
6
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
7
7
|
import { useSession } from 'nextjs-cms/auth/react'
|
|
8
|
-
import ContainerBox from '
|
|
9
|
-
import { Alert, AlertDescription } from '
|
|
8
|
+
import ContainerBox from '@/components/container-box'
|
|
9
|
+
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
10
10
|
|
|
11
11
|
type LocaleConfig = {
|
|
12
12
|
code: string
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { CSSProperties, forwardRef, Ref, useEffect, useImperativeHandle, useState } from 'react'
|
|
2
2
|
import { DropEvent, FileRejection, useDropzone } from 'react-dropzone'
|
|
3
3
|
import { DropzoneFile } from 'nextjs-cms/core/types'
|
|
4
|
-
import ContainerBox from '@/components/
|
|
4
|
+
import ContainerBox from '@/components/container-box'
|
|
5
5
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
6
6
|
import { MinusIcon } from '@radix-ui/react-icons'
|
|
7
7
|
import { useToast } from '@/components/ui/use-toast'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { trpc } from '@/app/_trpc/client'
|
|
2
|
-
import ProtectedImage from '@/components/
|
|
2
|
+
import ProtectedImage from '@/components/media/protected-image'
|
|
3
3
|
import { useToast } from '@/components/ui/use-toast'
|
|
4
|
-
import useModal from '@/
|
|
4
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
5
5
|
import { MinusIcon } from '@radix-ui/react-icons'
|
|
6
6
|
import { PhotoGalleryItem } from 'nextjs-cms/core/types'
|
|
7
7
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import ContainerBox from '@/components/
|
|
2
|
-
import GalleryPhoto from '@/components/
|
|
1
|
+
import ContainerBox from '@/components/container-box'
|
|
2
|
+
import GalleryPhoto from '@/components/media/gallery-photo'
|
|
3
3
|
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
4
4
|
import { PhotoGalleryItem } from 'nextjs-cms/core/types'
|
|
5
5
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Image from 'next/image'
|
|
2
2
|
import React, { useEffect } from 'react'
|
|
3
|
-
import { useAxiosPrivate } from 'nextjs-cms/
|
|
3
|
+
import { useAxiosPrivate } from 'nextjs-cms/api/client'
|
|
4
4
|
import { AxiosInstance } from 'axios'
|
|
5
5
|
import { base64ToBlob } from 'nextjs-cms/utils'
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
3
|
import { CheckIcon, XCircle, ChevronDown, XIcon, WandSparkles } from 'lucide-react'
|
|
4
|
-
|
|
4
|
+
import { env } from '@/env/env'
|
|
5
5
|
import { cn } from '@/lib/utils'
|
|
6
6
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
7
7
|
import { Separator } from '@/components/ui/separator'
|
|
@@ -532,7 +532,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
532
532
|
uniqueOptions.push(option)
|
|
533
533
|
}
|
|
534
534
|
})
|
|
535
|
-
if (
|
|
535
|
+
if (env.NODE_ENV === 'development' && duplicates.length > 0) {
|
|
536
536
|
const action = deduplicateOptions ? 'automatically removed' : 'detected'
|
|
537
537
|
console.warn(
|
|
538
538
|
`MultiSelect: Duplicate option values ${action}: ${duplicates.join(', ')}. ` +
|
|
@@ -549,7 +549,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
549
549
|
const getOptionByValue = React.useCallback(
|
|
550
550
|
(value: string): MultiSelectOption | undefined => {
|
|
551
551
|
const option = getAllOptions().find((option) => option.value === value)
|
|
552
|
-
if (!option &&
|
|
552
|
+
if (!option && env.NODE_ENV === 'development') {
|
|
553
553
|
console.warn(`MultiSelect: Option with value "${value}" not found in options list`)
|
|
554
554
|
}
|
|
555
555
|
return option
|
|
@@ -913,7 +913,11 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
913
913
|
handleClear()
|
|
914
914
|
}
|
|
915
915
|
}}
|
|
916
|
-
aria-label={
|
|
916
|
+
aria-label={
|
|
917
|
+
t('clearAllSelectedOptions', {
|
|
918
|
+
count: String(selectedValues.length),
|
|
919
|
+
}) as string
|
|
920
|
+
}
|
|
917
921
|
className='text-muted-foreground hover:text-foreground focus:ring-ring mx-2 flex h-4 w-4 cursor-pointer items-center justify-center rounded-sm focus:ring-2 focus:ring-offset-1 focus:outline-none'
|
|
918
922
|
>
|
|
919
923
|
<XIcon className='h-4 w-4' />
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import AdminCard from '@/components/
|
|
3
|
+
import AdminCard from '@/components/admin/admin-card'
|
|
4
4
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
5
|
-
import NewAdminForm from '@/components/
|
|
6
|
-
import ContainerBox from '@/components/
|
|
5
|
+
import NewAdminForm from '@/components/admin/new-admin-form'
|
|
6
|
+
import ContainerBox from '@/components/container-box'
|
|
7
7
|
import { trpc } from '@/app/_trpc/client'
|
|
8
|
-
import ErrorComponent from '
|
|
8
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
9
9
|
|
|
10
10
|
const AdminsPage = () => {
|
|
11
11
|
const t = useI18n()
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
import { useRef } from 'react'
|
|
4
4
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
5
|
-
import SectionItemCard from '@/components/
|
|
6
|
-
import ContainerBox from '@/components/
|
|
7
|
-
import Pagination from '@/components/pagination/
|
|
5
|
+
import SectionItemCard from '@/components/sections/section-item-card'
|
|
6
|
+
import ContainerBox from '@/components/container-box'
|
|
7
|
+
import Pagination from '@/components/pagination/pagination'
|
|
8
8
|
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
9
|
-
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '
|
|
10
|
-
import { Input } from '
|
|
11
|
-
import { Button } from '
|
|
9
|
+
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
|
|
10
|
+
import { Input } from '@/components/ui/input'
|
|
11
|
+
import { Button } from '@/components/ui/button'
|
|
12
12
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
13
13
|
import { trpc } from '@/app/_trpc/client'
|
|
14
14
|
import { capitalizeWords } from 'nextjs-cms/utils'
|
|
15
|
-
import ErrorComponent from '@/components/
|
|
15
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
16
16
|
|
|
17
17
|
export default function BrowsePage({ section, page }: { section: string; page: string }) {
|
|
18
18
|
const t = useI18n()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { trpc } from '@/app/_trpc/client'
|
|
4
|
-
import CategorySectionSelectInput from '@/components/
|
|
5
|
-
import ErrorComponent from '@/components/
|
|
4
|
+
import CategorySectionSelectInput from '@/components/sections/category-section-select-input'
|
|
5
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
6
6
|
|
|
7
7
|
export default function CategorizedSectionPage({ section }: { section: string }) {
|
|
8
8
|
const [data, {refetch}] = trpc.categorySections.get.useSuspenseQuery({
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useAxiosPrivate } from 'nextjs-cms/
|
|
3
|
+
import { useAxiosPrivate } from 'nextjs-cms/api/client'
|
|
4
4
|
import { RefObject, useCallback, useEffect, useRef, useState } from 'react'
|
|
5
5
|
import { SectionType } from 'nextjs-cms/core/types'
|
|
6
6
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
7
|
-
import useModal from '@/
|
|
7
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
8
8
|
import { AxiosError } from 'axios'
|
|
9
|
-
import InfoCard from '@/components/
|
|
9
|
+
import InfoCard from '@/components/feedback/info-card'
|
|
10
10
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
11
11
|
import { useToast } from '@/components/ui/use-toast'
|
|
12
|
-
import { DropzoneHandles } from '@/components/
|
|
13
|
-
import { VariantHandles } from '@/components/NewVariantComponent'
|
|
12
|
+
import { DropzoneHandles } from '@/components/media/dropzone'
|
|
14
13
|
import { trpc } from '@/app/_trpc/client'
|
|
15
|
-
import Form from '@/components/form/
|
|
16
|
-
import ErrorComponent from '@/components/
|
|
17
|
-
import LocaleSwitcher from '@/components/
|
|
14
|
+
import Form from '@/components/form/form'
|
|
15
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
16
|
+
import LocaleSwitcher from '@/components/locale/locale-switcher'
|
|
18
17
|
import { Trash2 } from 'lucide-react'
|
|
19
|
-
import { Alert, AlertDescription } from '
|
|
18
|
+
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
20
19
|
|
|
21
20
|
export default function ItemEditPage({
|
|
22
21
|
section,
|
|
@@ -50,7 +49,6 @@ export default function ItemEditPage({
|
|
|
50
49
|
const [formDirty, setFormDirty] = useState(false)
|
|
51
50
|
const handleDirtyChange = useCallback((isDirty: boolean) => setFormDirty(isDirty), [])
|
|
52
51
|
const dropzoneRef: RefObject<DropzoneHandles | null> = useRef(null)
|
|
53
|
-
const variantRef: RefObject<VariantHandles[]> = useRef([])
|
|
54
52
|
const [data, { refetch }] = trpc.hasItemsSections.editItem.useSuspenseQuery({
|
|
55
53
|
sectionName: section,
|
|
56
54
|
sectionItemId: itemId,
|
|
@@ -103,22 +101,6 @@ export default function ItemEditPage({
|
|
|
103
101
|
})
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
// Retrieve the variants from the variants component
|
|
107
|
-
// For now, only one variant is allowed
|
|
108
|
-
const variantsObject: any[] = []
|
|
109
|
-
if (variantRef.current && data?.section?.variants?.length && data?.section?.variants[0]) {
|
|
110
|
-
// Add variants to the body
|
|
111
|
-
variantRef.current.map((ref, index) => {
|
|
112
|
-
variantsObject.push({
|
|
113
|
-
// @ts-ignore
|
|
114
|
-
variant: data.section.variants[index],
|
|
115
|
-
items: ref.getVariants(),
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
formData.append(`variantItems`, JSON.stringify(variantsObject))
|
|
120
|
-
}
|
|
121
|
-
|
|
122
104
|
// Check if there are any hidden inputs passed to the component
|
|
123
105
|
if (hiddenInputs) {
|
|
124
106
|
// Add hidden inputs to the body
|
|
@@ -157,13 +139,6 @@ export default function ItemEditPage({
|
|
|
157
139
|
if (dropzoneRef.current) {
|
|
158
140
|
dropzoneRef.current.removeFiles()
|
|
159
141
|
}
|
|
160
|
-
|
|
161
|
-
// Clear Variants
|
|
162
|
-
if (variantRef.current) {
|
|
163
|
-
variantRef.current.map((ref) => {
|
|
164
|
-
ref.removeVariants()
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
142
|
await refetch()
|
|
168
143
|
setSubmitSuccessCount((currentCount) => currentCount + 1)
|
|
169
144
|
switch (sectionType) {
|
|
@@ -279,7 +254,6 @@ export default function ItemEditPage({
|
|
|
279
254
|
progress={progress}
|
|
280
255
|
data={data}
|
|
281
256
|
dropzoneRef={dropzoneRef}
|
|
282
|
-
variantRef={variantRef}
|
|
283
257
|
handleSubmit={handleSubmit}
|
|
284
258
|
isSubmitting={isSubmitting}
|
|
285
259
|
submitSuccessCount={submitSuccessCount}
|
|
@@ -4,7 +4,7 @@ import { useI18n } from 'nextjs-cms/translations/client'
|
|
|
4
4
|
import { trpc } from '@/app/_trpc/client'
|
|
5
5
|
import { Badge } from '@/components/ui/badge'
|
|
6
6
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
|
7
|
-
import ErrorComponent from '@/components/
|
|
7
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
8
8
|
import { Spinner } from '@/components/ui/spinner'
|
|
9
9
|
|
|
10
10
|
type LogMetadata = {
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useAxiosPrivate } from 'nextjs-cms/
|
|
3
|
+
import { useAxiosPrivate } from 'nextjs-cms/api/client'
|
|
4
4
|
import { RefObject, useEffect, useRef, useState } from 'react'
|
|
5
5
|
import { SectionType } from 'nextjs-cms/core/types'
|
|
6
6
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
7
|
-
import useModal from '@/
|
|
7
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
8
8
|
import { AxiosError } from 'axios'
|
|
9
|
-
import InfoCard from '@/components/
|
|
9
|
+
import InfoCard from '@/components/feedback/info-card'
|
|
10
10
|
import { useToast } from '@/components/ui/use-toast'
|
|
11
11
|
import { useRouter } from 'next/navigation'
|
|
12
|
-
import { DropzoneHandles } from '@/components/
|
|
13
|
-
import { VariantHandles } from '@/components/NewVariantComponent'
|
|
12
|
+
import { DropzoneHandles } from '@/components/media/dropzone'
|
|
14
13
|
import { trpc } from '@/app/_trpc/client'
|
|
15
|
-
import Form from '@/components/form/
|
|
16
|
-
import ErrorComponent from '@/components/
|
|
14
|
+
import Form from '@/components/form/form'
|
|
15
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
17
16
|
|
|
18
17
|
export default function NewPage({
|
|
19
18
|
section,
|
|
@@ -40,10 +39,9 @@ export default function NewPage({
|
|
|
40
39
|
const { toast } = useToast()
|
|
41
40
|
const router = useRouter()
|
|
42
41
|
const dropzoneRef: RefObject<DropzoneHandles | null> = useRef(null)
|
|
43
|
-
const variantRef: RefObject<VariantHandles[]> = useRef([])
|
|
44
42
|
const utils = trpc.useUtils()
|
|
45
43
|
|
|
46
|
-
const [data, {error, isError}] = trpc.hasItemsSections.newItem.useSuspenseQuery({
|
|
44
|
+
const [data, { error, isError }] = trpc.hasItemsSections.newItem.useSuspenseQuery({
|
|
47
45
|
sectionName: section,
|
|
48
46
|
})
|
|
49
47
|
|
|
@@ -64,22 +62,6 @@ export default function NewPage({
|
|
|
64
62
|
})
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
// Retrieve the variants from the variants component
|
|
68
|
-
// For now, only one variant is allowed
|
|
69
|
-
const variantsObject: any[] = []
|
|
70
|
-
if (variantRef.current && data?.section?.variants?.length && data?.section?.variants[0]) {
|
|
71
|
-
// Add variants to the body
|
|
72
|
-
variantRef.current.map((ref, index) => {
|
|
73
|
-
variantsObject.push({
|
|
74
|
-
// @ts-ignore
|
|
75
|
-
variant: data.section.variants[index],
|
|
76
|
-
items: ref.getVariants(),
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
formData.append(`variantItems`, JSON.stringify(variantsObject))
|
|
81
|
-
}
|
|
82
|
-
|
|
83
65
|
// Check if there are any hidden inputs passed to the component
|
|
84
66
|
if (hiddenInputs) {
|
|
85
67
|
// Add hidden inputs to the body
|
|
@@ -116,9 +98,7 @@ export default function NewPage({
|
|
|
116
98
|
toast({
|
|
117
99
|
variant: res.data?.errors?.length ? 'warning' : 'success',
|
|
118
100
|
title: t('itemCreatedSuccessfully'),
|
|
119
|
-
description: res.data?.errors?.length
|
|
120
|
-
? t('errorsInSubmit')
|
|
121
|
-
: t('itemCreatedSuccessfully'),
|
|
101
|
+
description: res.data?.errors?.length ? t('errorsInSubmit') : t('itemCreatedSuccessfully'),
|
|
122
102
|
})
|
|
123
103
|
|
|
124
104
|
switch (sectionType) {
|
|
@@ -173,34 +153,31 @@ export default function NewPage({
|
|
|
173
153
|
}, [])
|
|
174
154
|
|
|
175
155
|
if (data.error) {
|
|
176
|
-
|
|
156
|
+
return <ErrorComponent message={data.error.message} />
|
|
177
157
|
}
|
|
178
158
|
|
|
179
159
|
return (
|
|
180
160
|
<div className='flex w-full flex-col overflow-hidden'>
|
|
181
|
-
|
|
182
|
-
<div className='
|
|
183
|
-
<div className='
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
</span>
|
|
189
|
-
</div>
|
|
190
|
-
<Form
|
|
191
|
-
formType='new'
|
|
192
|
-
progressVariant={progressVariant}
|
|
193
|
-
response={response}
|
|
194
|
-
progress={progress}
|
|
195
|
-
data={data}
|
|
196
|
-
dropzoneRef={dropzoneRef}
|
|
197
|
-
variantRef={variantRef}
|
|
198
|
-
handleSubmit={handleSubmit}
|
|
199
|
-
isSubmitting={isSubmitting}
|
|
200
|
-
contentLocale={data.defaultLocale ?? undefined}
|
|
201
|
-
/>
|
|
161
|
+
<div className='flex w-full flex-col'>
|
|
162
|
+
<div className='text-foreground relative z-1 border-b-2 p-8 pt-12 font-extrabold'>
|
|
163
|
+
<div className='absolute top-0 left-0 z-2 h-4 w-full bg-linear-to-r from-emerald-800 via-emerald-400 to-sky-600'></div>
|
|
164
|
+
<h1 className='pb-4 text-4xl'>{data.section?.title.section}</h1>
|
|
165
|
+
<span>
|
|
166
|
+
/{t('new')} {data.section?.title.singular}
|
|
167
|
+
</span>
|
|
202
168
|
</div>
|
|
203
|
-
|
|
169
|
+
<Form
|
|
170
|
+
formType='new'
|
|
171
|
+
progressVariant={progressVariant}
|
|
172
|
+
response={response}
|
|
173
|
+
progress={progress}
|
|
174
|
+
data={data}
|
|
175
|
+
dropzoneRef={dropzoneRef}
|
|
176
|
+
handleSubmit={handleSubmit}
|
|
177
|
+
isSubmitting={isSubmitting}
|
|
178
|
+
contentLocale={data.defaultLocale ?? undefined}
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
204
181
|
</div>
|
|
205
182
|
)
|
|
206
183
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useAxiosPrivate } from 'nextjs-cms/
|
|
3
|
+
import { useAxiosPrivate } from 'nextjs-cms/api/client'
|
|
4
4
|
import { RefObject, useCallback, useEffect, useRef, useState } from 'react'
|
|
5
5
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
6
6
|
import { AxiosError } from 'axios'
|
|
7
|
-
import InfoCard from '@/components/
|
|
8
|
-
import { DropzoneHandles } from '@/components/
|
|
7
|
+
import InfoCard from '@/components/feedback/info-card'
|
|
8
|
+
import { DropzoneHandles } from '@/components/media/dropzone'
|
|
9
9
|
import { useToast } from '@/components/ui/use-toast'
|
|
10
10
|
import { trpc } from '@/app/_trpc/client'
|
|
11
|
-
import Form from '@/components/form/
|
|
12
|
-
import ErrorComponent from '
|
|
11
|
+
import Form from '@/components/form/form'
|
|
12
|
+
import ErrorComponent from '@/components/feedback/error-component'
|
|
13
13
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
14
|
-
import LocaleSwitcher from '@/components/
|
|
14
|
+
import LocaleSwitcher from '@/components/locale/locale-switcher'
|
|
15
15
|
import { Trash2 } from 'lucide-react'
|
|
16
|
-
import { Alert, AlertDescription } from '
|
|
16
|
+
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
17
17
|
|
|
18
18
|
export default function SectionPage({ section }: { section: string }) {
|
|
19
19
|
const t = useI18n()
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import React, { useEffect, useState } from 'react'
|
|
4
4
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
5
|
-
import useModal from '@/
|
|
6
|
-
import InfoCard from '@/components/
|
|
7
|
-
import LoadingSpinners from '@/components/
|
|
5
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
6
|
+
import InfoCard from '@/components/feedback/info-card'
|
|
7
|
+
import LoadingSpinners from '@/components/feedback/loading-spinners'
|
|
8
8
|
import { useToast } from '@/components/ui/use-toast'
|
|
9
9
|
import { trpc } from '@/app/_trpc/client'
|
|
10
|
-
import Form from '@/components/form/
|
|
10
|
+
import Form from '@/components/form/form'
|
|
11
11
|
|
|
12
12
|
export default function SettingsPage() {
|
|
13
13
|
const t = useI18n()
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import LoadingSpinners from '@/components/
|
|
2
|
-
import InfoCard from '@/components/
|
|
1
|
+
import LoadingSpinners from '@/components/feedback/loading-spinners'
|
|
2
|
+
import InfoCard from '@/components/feedback/info-card'
|
|
3
3
|
import React from 'react'
|
|
4
4
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
5
5
|
import { Button } from '@/components/ui/button'
|
|
6
|
-
import useModal from '@/
|
|
6
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
7
7
|
import { useToast } from '@/components/ui/use-toast'
|
|
8
8
|
import { trpc } from '@/app/_trpc/client'
|
|
9
|
-
import { Switch } from '
|
|
9
|
+
import { Switch } from '@/components/ui/switch'
|
|
10
10
|
import { Label } from '@/components/ui/label'
|
|
11
11
|
|
|
12
12
|
export default function CategoryDeleteConfirmPage({
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import FormInputElement from '@/components/form/
|
|
3
|
-
import SelectBox from '@/components/
|
|
4
|
-
import LoadingSpinners from '@/components/
|
|
2
|
+
import FormInputElement from '@/components/form/form-input-element'
|
|
3
|
+
import SelectBox from '@/components/select-box'
|
|
4
|
+
import LoadingSpinners from '@/components/feedback/loading-spinners'
|
|
5
5
|
import { useAutoAnimate } from '@formkit/auto-animate/react'
|
|
6
|
-
import SelectInputButtons from '@/components/
|
|
6
|
+
import SelectInputButtons from '@/components/sections/select-input-buttons'
|
|
7
7
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
8
8
|
import { trpc } from '@/app/_trpc/client'
|
|
9
9
|
import { SelectOption } from 'nextjs-cms/core/fields'
|
|
10
|
-
import type { RouterOutputs } from '
|
|
10
|
+
import type { RouterOutputs } from '@/app/_trpc/types'
|
|
11
11
|
import { nanoid } from 'nanoid'
|
|
12
12
|
|
|
13
13
|
type CategorySelect = RouterOutputs['categorySections']['get']['data']
|
package/templates/default/components/{ConditionalFields.tsx → sections/conditional-fields.tsx}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldClientConfig } from 'nextjs-cms/core/fields'
|
|
2
2
|
import React, { useEffect, useState } from 'react'
|
|
3
|
-
import FormInputs from '@/components/form/
|
|
3
|
+
import FormInputs from '@/components/form/form-inputs'
|
|
4
4
|
import { ConditionalField } from 'nextjs-cms/core/types'
|
|
5
5
|
|
|
6
6
|
export function ConditionalFields({
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
3
|
-
import useModal from '@/
|
|
4
|
-
import ProtectedImage from '@/components/
|
|
5
|
-
import SectionItemStatusBadge from '@/components/
|
|
3
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
4
|
+
import ProtectedImage from '@/components/media/protected-image'
|
|
5
|
+
import SectionItemStatusBadge from '@/components/sections/section-item-status-badge'
|
|
6
6
|
import { displayDateFromString } from 'nextjs-cms/utils'
|
|
7
7
|
import Link from 'next/link'
|
|
8
8
|
import { CardTitle, CardHeader, CardFooter, Card, CardContent } from '@/components/ui/card'
|
|
9
9
|
import { Button } from '@/components/ui/button'
|
|
10
10
|
import { PersonIcon } from '@radix-ui/react-icons'
|
|
11
11
|
import { trpc } from '@/app/_trpc/client'
|
|
12
|
-
import type { RouterOutputs } from '
|
|
12
|
+
import type { RouterOutputs } from '@/app/_trpc/types'
|
|
13
13
|
|
|
14
14
|
// Used to get elements of array types as types
|
|
15
15
|
type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[] ? ElementType : never
|
package/templates/default/components/{SelectInputButtons.tsx → sections/select-input-buttons.tsx}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
-
import useModal from '@/
|
|
2
|
+
import { useModal } from '@/components/feedback/modal-context'
|
|
3
3
|
import React from 'react'
|
|
4
|
-
import NewPage from '@/components/
|
|
5
|
-
import ItemEditPage from '@/components/
|
|
4
|
+
import NewPage from '@/components/pages/new-page'
|
|
5
|
+
import ItemEditPage from '@/components/pages/item-edit-page'
|
|
6
6
|
import { Button } from '@/components/ui/button'
|
|
7
|
-
import CategoryDeleteConfirmPage from '@/components/
|
|
7
|
+
import CategoryDeleteConfirmPage from '@/components/sections/category-delete-confirm-page'
|
|
8
8
|
|
|
9
9
|
export default function SelectInputButtons({
|
|
10
10
|
section,
|
|
@@ -46,9 +46,25 @@ export const TestSectionTable = mysqlTable('test_section', {
|
|
|
46
46
|
|
|
47
47
|
export const TestTagsTable = mysqlTable('test_tags', {
|
|
48
48
|
testId: int('test_id').notNull(),
|
|
49
|
-
tagName: varchar('tag_name', { length: 255 }).notNull()
|
|
49
|
+
tagName: varchar('tag_name', { length: 255 }).notNull(),
|
|
50
|
+
locale: varchar('locale', { length: 255 }).notNull()
|
|
50
51
|
}, (table) => [
|
|
51
|
-
primaryKey({ columns: [table.testId, table.tagName] })
|
|
52
|
+
primaryKey({ columns: [table.testId, table.tagName, table.locale] })
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
export const TestSectionLocalesTable = mysqlTable('test_section_locales', {
|
|
57
|
+
id: int('id').autoincrement().notNull().primaryKey(),
|
|
58
|
+
parentId: int('parent_id').notNull(),
|
|
59
|
+
locale: varchar('locale', { length: 10 }).notNull(),
|
|
60
|
+
contentType: mysqlEnum('content_type', ['ad', 'user']).notNull(),
|
|
61
|
+
price: int('price'),
|
|
62
|
+
appId: varchar('app_id', { length: 36 }).notNull(),
|
|
63
|
+
title: varchar('title', { length: 255 }).notNull(),
|
|
64
|
+
photo: varchar('photo', { length: 255 }),
|
|
65
|
+
category: varchar('category', { length: 255 }).notNull()
|
|
66
|
+
}, (table) => [
|
|
67
|
+
unique('test_section_locales_parent_id_locale_unique').on(table.parentId, table.locale)
|
|
52
68
|
]);
|
|
53
69
|
|
|
54
70
|
|
|
@@ -619,6 +635,32 @@ export const AddressTable = mysqlTable('address', {
|
|
|
619
635
|
});
|
|
620
636
|
|
|
621
637
|
|
|
638
|
+
export const E2eRequiredFieldsTable = mysqlTable('e2e_required_fields', {
|
|
639
|
+
id: int('id').autoincrement().notNull().primaryKey(),
|
|
640
|
+
title: varchar('title', { length: 255 }).notNull(),
|
|
641
|
+
slug: varchar('slug', { length: 255 }).notNull(),
|
|
642
|
+
subtitle: longtext('subtitle').notNull(),
|
|
643
|
+
secret: varchar('secret', { length: 255 }).notNull(),
|
|
644
|
+
quantity: int('quantity').notNull(),
|
|
645
|
+
price: float('price').notNull(),
|
|
646
|
+
rating: double('rating').notNull(),
|
|
647
|
+
isPublished: boolean('is_published').notNull(),
|
|
648
|
+
status: mysqlEnum('status', ['draft', 'published', 'archived']).notNull(),
|
|
649
|
+
categories: varchar('categories', { length: 255 }).notNull(),
|
|
650
|
+
tags: varchar('tags', { length: 255 }).notNull(),
|
|
651
|
+
coverPhoto: varchar('cover_photo', { length: 255 }).notNull(),
|
|
652
|
+
videoClip: varchar('video_clip', { length: 255 }).notNull(),
|
|
653
|
+
attachment: varchar('attachment', { length: 255 }).notNull(),
|
|
654
|
+
bodyContent: longtext('body_content').notNull(),
|
|
655
|
+
publishDate: date('publish_date').notNull(),
|
|
656
|
+
startsAt: datetime('starts_at').notNull(),
|
|
657
|
+
availableFrom: date('available_from'),
|
|
658
|
+
availableUntil: date('available_until'),
|
|
659
|
+
brandColor: varchar('brand_color', { length: 7 }).notNull(),
|
|
660
|
+
mapLocation: varchar('map_location', { length: 255 })
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
|
|
622
664
|
export const E2eOptionalFieldsTable = mysqlTable('e2e_optional_fields', {
|
|
623
665
|
id: int('id').autoincrement().notNull().primaryKey(),
|
|
624
666
|
title: varchar('title', { length: 255 }),
|