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.
Files changed (127) hide show
  1. package/package.json +3 -3
  2. package/templates/default/app/(auth)/auth/login/LoginPage.tsx +2 -2
  3. package/templates/default/app/(auth)/layout.tsx +1 -1
  4. package/templates/default/app/(rootLayout)/(plugins)/[...slug]/page.tsx +47 -40
  5. package/templates/default/app/(rootLayout)/(plugins)/[...slug]/plugin-server-registry.ts +16 -16
  6. package/templates/default/app/(rootLayout)/admins/page.tsx +2 -2
  7. package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +2 -2
  8. package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +2 -2
  9. package/templates/default/app/(rootLayout)/dashboard/page.tsx +10 -3
  10. package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +2 -2
  11. package/templates/default/app/(rootLayout)/layout.tsx +3 -3
  12. package/templates/default/app/(rootLayout)/loading.tsx +1 -1
  13. package/templates/default/app/(rootLayout)/log/page.tsx +1 -1
  14. package/templates/default/app/(rootLayout)/new/[section]/page.tsx +2 -2
  15. package/templates/default/app/(rootLayout)/section/[section]/page.tsx +2 -2
  16. package/templates/default/app/(rootLayout)/settings/page.tsx +2 -2
  17. package/templates/default/app/_trpc/client.tsx +6 -0
  18. package/templates/default/app/_trpc/server.ts +9 -0
  19. package/templates/default/app/_trpc/types.ts +6 -0
  20. package/templates/default/app/api/document/route.ts +1 -1
  21. package/templates/default/app/api/photo/route.ts +1 -1
  22. package/templates/default/app/api/trpc/[trpc]/route.ts +3 -33
  23. package/templates/default/app/api/video/route.ts +1 -1
  24. package/templates/default/app/providers.tsx +20 -152
  25. package/templates/default/cms.config.ts +4 -2
  26. package/templates/default/components/{AdminCard.tsx → admin/admin-card.tsx} +4 -4
  27. package/templates/default/components/{AdminEditPage.tsx → admin/admin-edit-page.tsx} +3 -3
  28. package/templates/default/components/{AdminPrivilegeCard.tsx → admin/admin-privilege-card.tsx} +1 -1
  29. package/templates/default/components/{NewAdminForm.tsx → admin/new-admin-form.tsx} +4 -4
  30. package/templates/default/components/{ContainerBox.tsx → container-box.tsx} +1 -1
  31. package/templates/default/components/{ErrorComponent.tsx → feedback/error-component.tsx} +1 -1
  32. package/templates/default/{context/ModalProvider.tsx → components/feedback/modal-context.tsx} +56 -53
  33. package/templates/default/components/{Modal.tsx → feedback/modal.tsx} +1 -1
  34. package/templates/default/components/form/{FormInputs.tsx → form-inputs.tsx} +17 -17
  35. package/templates/default/components/form/{Form.tsx → form.tsx} +17 -11
  36. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  37. package/templates/default/components/form/inputs/{CheckboxFormInput.tsx → checkbox-form-input.tsx} +1 -1
  38. package/templates/default/components/form/inputs/{ColorFormInput.tsx → color-form-input.tsx} +1 -1
  39. package/templates/default/components/form/inputs/{DateFormInput.tsx → date-form-input.tsx} +1 -1
  40. package/templates/default/components/form/inputs/{DateRangeFormInput.tsx → date-range-form-input.tsx} +1 -1
  41. package/templates/default/components/form/inputs/{DocumentFormInput.tsx → document-form-input.tsx} +3 -3
  42. package/templates/default/components/form/inputs/{MapFormInput.tsx → map-form-input.tsx} +5 -4
  43. package/templates/default/components/form/inputs/{MultipleSelectFormInput.tsx → multiple-select-form-input.tsx} +1 -1
  44. package/templates/default/components/form/inputs/{NumberFormInput.tsx → number-form-input.tsx} +1 -1
  45. package/templates/default/components/form/inputs/{PasswordFormInput.tsx → password-form-input.tsx} +1 -1
  46. package/templates/default/components/form/inputs/{PhotoFormInput.tsx → photo-form-input.tsx} +3 -3
  47. package/templates/default/components/form/inputs/{RichTextFormInput.tsx → rich-text-form-input.tsx} +3 -3
  48. package/templates/default/components/form/inputs/{SelectFormInput.tsx → select-form-input.tsx} +4 -4
  49. package/templates/default/components/form/inputs/{SlugFormInput.tsx → slug-form-input.tsx} +1 -1
  50. package/templates/default/components/form/inputs/{TagsFormInput.tsx → tags-form-input.tsx} +1 -1
  51. package/templates/default/components/form/inputs/{TextFormInput.tsx → text-form-input.tsx} +3 -3
  52. package/templates/default/components/form/inputs/{TextareaFormInput.tsx → textarea-form-input.tsx} +2 -2
  53. package/templates/default/components/form/inputs/{VideoFormInput.tsx → video-form-input.tsx} +3 -3
  54. package/templates/default/components/{Layout.tsx → layout/layout.tsx} +4 -4
  55. package/templates/default/components/{Navbar.tsx → layout/navbar.tsx} +2 -2
  56. package/templates/default/components/{SidebarDropdownItem.tsx → layout/sidebar-dropdown-item.tsx} +1 -1
  57. package/templates/default/components/{SidebarItem.tsx → layout/sidebar-item.tsx} +1 -1
  58. package/templates/default/components/layout/sidebar-plugin-group.tsx +63 -0
  59. package/templates/default/components/{Sidebar.tsx → layout/sidebar.tsx} +28 -3
  60. package/templates/default/components/{LocaleSwitcher.tsx → locale/locale-switcher.tsx} +2 -2
  61. package/templates/default/components/{Dropzone.tsx → media/dropzone.tsx} +1 -1
  62. package/templates/default/components/{GalleryPhoto.tsx → media/gallery-photo.tsx} +2 -2
  63. package/templates/default/components/{PhotoGallery.tsx → media/photo-gallery.tsx} +2 -2
  64. package/templates/default/components/{ProtectedImage.tsx → media/protected-image.tsx} +1 -1
  65. package/templates/default/components/multi-select.tsx +8 -4
  66. package/templates/default/components/{AdminsPage.tsx → pages/admins-page.tsx} +4 -4
  67. package/templates/default/components/{BrowsePage.tsx → pages/browse-page.tsx} +7 -7
  68. package/templates/default/components/{CategorizedSectionPage.tsx → pages/categorized-section-page.tsx} +2 -2
  69. package/templates/default/components/{ItemEditPage.tsx → pages/item-edit-page.tsx} +8 -34
  70. package/templates/default/components/{LogPage.tsx → pages/log-page.tsx} +1 -1
  71. package/templates/default/components/{NewPage.tsx → pages/new-page.tsx} +28 -51
  72. package/templates/default/components/{SectionPage.tsx → pages/section-page.tsx} +7 -7
  73. package/templates/default/components/{SettingsPage.tsx → pages/settings-page.tsx} +4 -4
  74. package/templates/default/components/pagination/{Pagination.tsx → pagination.tsx} +1 -1
  75. package/templates/default/components/{CategoryDeleteConfirmPage.tsx → sections/category-delete-confirm-page.tsx} +4 -4
  76. package/templates/default/components/{CategorySectionSelectInput.tsx → sections/category-section-select-input.tsx} +5 -5
  77. package/templates/default/components/{ConditionalFields.tsx → sections/conditional-fields.tsx} +1 -1
  78. package/templates/default/components/{SectionItemCard.tsx → sections/section-item-card.tsx} +4 -4
  79. package/templates/default/components/{SelectInputButtons.tsx → sections/select-input-buttons.tsx} +4 -4
  80. package/templates/default/dynamic-schemas/schema.ts +44 -2
  81. package/templates/default/env/env.ts +42 -0
  82. package/templates/default/next.config.ts +1 -0
  83. package/templates/default/package.json +2 -1
  84. package/templates/default/app/_trpc/client.ts +0 -3
  85. package/templates/default/components/AnalyticsPage.tsx +0 -144
  86. package/templates/default/components/BarChartBox.tsx +0 -42
  87. package/templates/default/components/NewVariantComponent.tsx +0 -229
  88. package/templates/default/components/PieChartBox.tsx +0 -101
  89. package/templates/default/components/VariantCard.tsx +0 -124
  90. package/templates/default/components/VariantEditPage.tsx +0 -230
  91. package/templates/default/components/analytics/BounceRate.tsx +0 -70
  92. package/templates/default/components/analytics/LivePageViews.tsx +0 -55
  93. package/templates/default/components/analytics/LiveUsersCount.tsx +0 -33
  94. package/templates/default/components/analytics/MonthlyPageViews.tsx +0 -42
  95. package/templates/default/components/analytics/TopCountries.tsx +0 -52
  96. package/templates/default/components/analytics/TopDevices.tsx +0 -46
  97. package/templates/default/components/analytics/TopMediums.tsx +0 -58
  98. package/templates/default/components/analytics/TopSources.tsx +0 -45
  99. package/templates/default/components/analytics/TotalPageViews.tsx +0 -41
  100. package/templates/default/components/analytics/TotalSessions.tsx +0 -41
  101. package/templates/default/components/analytics/TotalUniqueUsers.tsx +0 -41
  102. package/templates/default/components/custom/RightHomeRoomVariantCard.tsx +0 -138
  103. package/templates/default/env/env.js +0 -130
  104. package/templates/default/hooks/useModal.ts +0 -8
  105. package/templates/default/lib/apiHelpers.ts +0 -92
  106. /package/templates/default/components/{dndKit/Draggable.tsx → dnd-kit/draggable.tsx} +0 -0
  107. /package/templates/default/components/{dndKit/Droppable.tsx → dnd-kit/droppable.tsx} +0 -0
  108. /package/templates/default/components/{dndKit/SortableItem.tsx → dnd-kit/sortable-item.tsx} +0 -0
  109. /package/templates/default/components/{InfoCard.tsx → feedback/info-card.tsx} +0 -0
  110. /package/templates/default/components/{LoadingSpinners.tsx → feedback/loading-spinners.tsx} +0 -0
  111. /package/templates/default/components/{ProgressBar.tsx → feedback/progress-bar.tsx} +0 -0
  112. /package/templates/default/components/{TooltipComponent.tsx → feedback/tooltip-component.tsx} +0 -0
  113. /package/templates/default/components/form/{ContentLocaleContext.tsx → content-locale-context.tsx} +0 -0
  114. /package/templates/default/components/form/{FormInputElement.tsx → form-input-element.tsx} +0 -0
  115. /package/templates/default/components/{language-dropdown.tsx → i18n/language-dropdown.tsx} +0 -0
  116. /package/templates/default/components/{language-picker.tsx → i18n/language-picker.tsx} +0 -0
  117. /package/templates/default/components/{login-language-dropdown.tsx → i18n/login-language-dropdown.tsx} +0 -0
  118. /package/templates/default/components/{DefaultNavItems.tsx → layout/default-nav-items.tsx} +0 -0
  119. /package/templates/default/components/{ThemeProvider.tsx → layout/theme-provider.tsx} +0 -0
  120. /package/templates/default/components/{theme-toggle.tsx → layout/theme-toggle.tsx} +0 -0
  121. /package/templates/default/components/{ProtectedDocument.tsx → media/protected-document.tsx} +0 -0
  122. /package/templates/default/components/{ProtectedVideo.tsx → media/protected-video.tsx} +0 -0
  123. /package/templates/default/components/{DashboardPageAlt.tsx → pages/dashboard-page-alt.tsx} +0 -0
  124. /package/templates/default/components/pagination/{PaginationButtons.tsx → pagination-buttons.tsx} +0 -0
  125. /package/templates/default/components/{SectionIcon.tsx → sections/section-icon.tsx} +0 -0
  126. /package/templates/default/components/{SectionItemStatusBadge.tsx → sections/section-item-status-badge.tsx} +0 -0
  127. /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/SidebarItem'
7
- import SidebarDropdownItem from '@/components/SidebarDropdownItem'
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/ProtectedImage'
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 './ContainerBox'
9
- import { Alert, AlertDescription } from './ui/alert'
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/ContainerBox'
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/ProtectedImage'
2
+ import ProtectedImage from '@/components/media/protected-image'
3
3
  import { useToast } from '@/components/ui/use-toast'
4
- import useModal from '@/hooks/useModal'
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/ContainerBox'
2
- import GalleryPhoto from '@/components/GalleryPhoto'
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/auth/hooks'
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 (process.env.NODE_ENV === 'development' && duplicates.length > 0) {
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 && process.env.NODE_ENV === 'development') {
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={t('clearAllSelectedOptions', { count: String(selectedValues.length) }) as string}
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/AdminCard'
3
+ import AdminCard from '@/components/admin/admin-card'
4
4
  import { useI18n } from 'nextjs-cms/translations/client'
5
- import NewAdminForm from '@/components/NewAdminForm'
6
- import ContainerBox from '@/components/ContainerBox'
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 './ErrorComponent'
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/SectionItemCard'
6
- import ContainerBox from '@/components/ContainerBox'
7
- import Pagination from '@/components/pagination/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 './ui/card'
10
- import { Input } from './ui/input'
11
- import { Button } from './ui/button'
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/ErrorComponent'
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/CategorySectionSelectInput'
5
- import ErrorComponent from '@/components/ErrorComponent'
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/auth/hooks'
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 '@/hooks/useModal'
7
+ import { useModal } from '@/components/feedback/modal-context'
8
8
  import { AxiosError } from 'axios'
9
- import InfoCard from '@/components/InfoCard'
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/Dropzone'
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/Form'
16
- import ErrorComponent from '@/components/ErrorComponent'
17
- import LocaleSwitcher from '@/components/LocaleSwitcher'
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 './ui/alert'
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/ErrorComponent'
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/auth/hooks'
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 '@/hooks/useModal'
7
+ import { useModal } from '@/components/feedback/modal-context'
8
8
  import { AxiosError } from 'axios'
9
- import InfoCard from '@/components/InfoCard'
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/Dropzone'
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/Form'
16
- import ErrorComponent from '@/components/ErrorComponent'
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
- return <ErrorComponent message={data.error.message} />
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='flex w-full flex-col'>
183
- <div className='text-foreground relative z-1 border-b-2 p-8 pt-12 font-extrabold'>
184
- <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>
185
- <h1 className='pb-4 text-4xl'>{data.section?.title.section}</h1>
186
- <span>
187
- /{t('new')} {data.section?.title.singular}
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/auth/hooks'
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/InfoCard'
8
- import { DropzoneHandles } from '@/components/Dropzone'
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/Form'
12
- import ErrorComponent from './ErrorComponent'
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/LocaleSwitcher'
14
+ import LocaleSwitcher from '@/components/locale/locale-switcher'
15
15
  import { Trash2 } from 'lucide-react'
16
- import { Alert, AlertDescription } from './ui/alert'
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 '@/hooks/useModal'
6
- import InfoCard from '@/components/InfoCard'
7
- import LoadingSpinners from '@/components/LoadingSpinners'
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/Form'
10
+ import Form from '@/components/form/form'
11
11
 
12
12
  export default function SettingsPage() {
13
13
  const t = useI18n()
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import PaginationButtons from './PaginationButtons'
2
+ import PaginationButtons from '@/components/pagination/pagination-buttons'
3
3
 
4
4
  export default function Pagination({
5
5
  page,
@@ -1,12 +1,12 @@
1
- import LoadingSpinners from '@/components/LoadingSpinners'
2
- import InfoCard from '@/components/InfoCard'
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 '@/hooks/useModal'
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 './ui/switch'
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/FormInputElement'
3
- import SelectBox from '@/components/SelectBox'
4
- import LoadingSpinners from '@/components/LoadingSpinners'
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/SelectInputButtons'
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 'nextjs-cms/api'
10
+ import type { RouterOutputs } from '@/app/_trpc/types'
11
11
  import { nanoid } from 'nanoid'
12
12
 
13
13
  type CategorySelect = RouterOutputs['categorySections']['get']['data']
@@ -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/FormInputs'
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 '@/hooks/useModal'
4
- import ProtectedImage from '@/components/ProtectedImage'
5
- import SectionItemStatusBadge from '@/components/SectionItemStatusBadge'
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 'nextjs-cms/api'
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
@@ -1,10 +1,10 @@
1
1
  import { useI18n } from 'nextjs-cms/translations/client'
2
- import useModal from '@/hooks/useModal'
2
+ import { useModal } from '@/components/feedback/modal-context'
3
3
  import React from 'react'
4
- import NewPage from '@/components/NewPage'
5
- import ItemEditPage from '@/components/ItemEditPage'
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/CategoryDeleteConfirmPage'
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 }),