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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nextjs-cms",
3
- "version": "0.9.22",
3
+ "version": "0.9.24",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,8 +29,8 @@
29
29
  "tsx": "^4.20.6",
30
30
  "typescript": "^5.9.2",
31
31
  "@lzcms/eslint-config": "0.3.0",
32
- "@lzcms/prettier-config": "0.1.0",
33
- "@lzcms/tsconfig": "0.1.0"
32
+ "@lzcms/tsconfig": "0.1.0",
33
+ "@lzcms/prettier-config": "0.1.0"
34
34
  },
35
35
  "prettier": "@lzcms/prettier-config",
36
36
  "scripts": {
@@ -3,7 +3,7 @@
3
3
  import React, { useEffect, useRef, useState } from 'react'
4
4
  import { useRouter, useSearchParams } from 'next/navigation'
5
5
  import { useI18n } from 'nextjs-cms/translations/client'
6
- import InfoCard from '@/components/InfoCard'
6
+ import InfoCard from '@/components/feedback/info-card'
7
7
  import Link from 'next/link'
8
8
  import { Switch } from '@/components/ui/switch'
9
9
  import { Label } from '@/components/ui/label'
@@ -12,7 +12,7 @@ import { MoonIcon, SunIcon } from '@radix-ui/react-icons'
12
12
  import { useTheme } from 'next-themes'
13
13
  import { login, useSession } from 'nextjs-cms/auth/react'
14
14
  import { wasLanguageChangedOnLogin } from 'nextjs-cms/translations'
15
- import LoginLanguageDropdown from '@/components/login-language-dropdown'
15
+ import LoginLanguageDropdown from '@/components/i18n/login-language-dropdown'
16
16
  import { useAuthLanguage } from '../../auth-language-provider'
17
17
 
18
18
  type fromErrors = {
@@ -3,7 +3,7 @@ import { cookies } from 'next/headers'
3
3
  import '../globals.css'
4
4
  import type { Metadata } from 'next'
5
5
  import { cn } from '@/lib/utils'
6
- import { ThemeProvider } from '@/components/ThemeProvider'
6
+ import { ThemeProvider } from '@/components/layout/theme-provider'
7
7
  import Providers from '@/app/providers'
8
8
  import auth from 'nextjs-cms/auth'
9
9
  import { getCMSConfig } from 'nextjs-cms/core'
@@ -1,40 +1,47 @@
1
- import { notFound } from 'next/navigation'
2
- import auth from 'nextjs-cms/auth'
3
- import { getAdminPrivileges } from 'nextjs-cms/api/helpers'
4
- import { findPluginRouteByPath, isDashboardOverridePlugin } from 'nextjs-cms/plugins/server'
5
- import { getPluginServerComponent } from './plugin-server-registry'
6
-
7
- export const dynamic = 'force-dynamic'
8
- type Params = Promise<{ slug?: string[] }>
9
-
10
- export default async function Page(props: { params: Params }) {
11
- const params = await props.params
12
- const slug = params.slug ?? []
13
-
14
- const path = `/${slug.join('/')}`
15
- const session = await auth()
16
- if (!session?.user) {
17
- notFound()
18
- }
19
-
20
- const plugin = await findPluginRouteByPath(path)
21
- if (!plugin) {
22
- notFound()
23
- }
24
-
25
- // Bypass privilege check for dashboard override plugin
26
- const isDashboardPlugin = await isDashboardOverridePlugin(plugin.pluginName)
27
- if (!isDashboardPlugin) {
28
- const privilegeSet = await getAdminPrivileges(session.user.id)
29
- if (!privilegeSet.has(plugin.pluginName)) {
30
- notFound()
31
- }
32
- }
33
-
34
- const PluginComponent = await getPluginServerComponent(plugin.pluginRegistryName, plugin.component)
35
- if (!PluginComponent) {
36
- notFound()
37
- }
38
-
39
- return <PluginComponent />
40
- }
1
+ import { notFound } from 'next/navigation'
2
+ import auth from 'nextjs-cms/auth'
3
+ import { getAdminPrivileges } from 'nextjs-cms/api/server/actions'
4
+ import { findPluginRouteByPath, isDashboardOverridePlugin, runRoutePrefetches } from 'nextjs-cms/plugins/server'
5
+ import { api, HydrateClient } from '@/app/_trpc/server'
6
+ import { getPluginServerComponent } from './plugin-server-registry'
7
+
8
+ export const dynamic = 'force-dynamic'
9
+ type Params = Promise<{ slug?: string[] }>
10
+
11
+ export default async function Page(props: { params: Params }) {
12
+ const params = await props.params
13
+ const slug = params.slug ?? []
14
+
15
+ const path = `/${slug.join('/')}`
16
+ const session = await auth()
17
+ if (!session?.user) {
18
+ notFound()
19
+ }
20
+
21
+ const plugin = await findPluginRouteByPath(path)
22
+ if (!plugin) {
23
+ notFound()
24
+ }
25
+
26
+ // Bypass privilege check for dashboard override plugin
27
+ const isDashboardPlugin = await isDashboardOverridePlugin(plugin.pluginName)
28
+ if (!isDashboardPlugin) {
29
+ const privilegeSet = await getAdminPrivileges(session.user.id)
30
+ if (!privilegeSet.has(plugin.pluginName)) {
31
+ notFound()
32
+ }
33
+ }
34
+
35
+ const PluginComponent = await getPluginServerComponent(plugin.pluginName, plugin.component)
36
+ if (!PluginComponent) {
37
+ notFound()
38
+ }
39
+
40
+ await runRoutePrefetches(api, plugin)
41
+
42
+ return (
43
+ <HydrateClient>
44
+ <PluginComponent />
45
+ </HydrateClient>
46
+ )
47
+ }
@@ -1,22 +1,22 @@
1
- import dynamic from 'next/dynamic'
2
-
1
+ import type { ComponentType } from 'react'
2
+
3
3
  export const pluginNamesMap: Record<string, string> = {
4
4
  'cpanel-dashboard': '@nextjscms/plugin-cpanel-dashboard/server',
5
5
  'cpanel-emails': '@nextjscms/plugin-cpanel-emails/server',
6
6
  'google-analytics': '@nextjscms/plugin-google-analytics/server',
7
7
  // A workaround to avoid importing error if no plugins are installed
8
8
  blank: 'nextjs-cms/plugins/blank-component',
9
- }
10
-
11
- export const getPluginServerComponent = async (registryName: string, componentName: string | undefined) => {
12
- const pluginName = pluginNamesMap[registryName]
13
- const ClientComponent = dynamic(
14
- () =>
15
- import(pluginName ?? 'nextjs-cms/plugins/blank-component').then((mod) =>
16
- componentName ? mod[componentName] : mod.default,
17
- ),
18
- { ssr: true },
19
- )
20
-
21
- return ClientComponent
22
- }
9
+ }
10
+
11
+ export const getPluginServerComponent = async (
12
+ pluginName: string,
13
+ componentName: string | undefined,
14
+ ): Promise<ComponentType | null> => {
15
+ const modulePath = pluginNamesMap[pluginName] ?? pluginNamesMap.blank
16
+ if (!modulePath) return null
17
+
18
+ const mod = (await import(modulePath)) as Record<string, unknown>
19
+ const component = (componentName ? mod[componentName] : mod.default) as ComponentType | undefined
20
+
21
+ return component ?? null
22
+ }
@@ -1,5 +1,5 @@
1
- import AdminsPage from '@/components/AdminsPage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import AdminsPage from '@/components/pages/admins-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
  export default async function Page() {
4
4
  await api.admins.list.prefetch()
5
5
  return (
@@ -1,5 +1,5 @@
1
- import BrowsePage from '@/components/BrowsePage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import BrowsePage from '@/components/pages/browse-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
  type Params = Promise<{ section: string; page: string }>
4
4
  type SearchParams = Promise<{ q: string | undefined }>
5
5
  export default async function Page(props: { params: Params; searchParams: SearchParams }) {
@@ -1,5 +1,5 @@
1
- import CategorizedSectionPage from '@/components/CategorizedSectionPage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import CategorizedSectionPage from '@/components/pages/categorized-section-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
  type Params = Promise<{ section: string }>
4
4
 
5
5
  export default async function Page(props: { params: Params }) {
@@ -1,4 +1,5 @@
1
- import { getDashboardOverride } from 'nextjs-cms/plugins/server'
1
+ import { getDashboardOverride, runRoutePrefetches } from 'nextjs-cms/plugins/server'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
2
3
  import { getPluginServerComponent } from '../(plugins)/[...slug]/plugin-server-registry'
3
4
 
4
5
  export const dynamic = 'force-dynamic'
@@ -54,10 +55,16 @@ export default async function DashboardPage() {
54
55
  }
55
56
 
56
57
  // Render the override plugin component (no privilege check for dashboard override)
57
- const PluginComponent = await getPluginServerComponent(override.pluginRegistryName, override.component)
58
+ const PluginComponent = await getPluginServerComponent(override.pluginName, override.component)
58
59
  if (!PluginComponent) {
59
60
  return <DefaultDashboard />
60
61
  }
61
62
 
62
- return <PluginComponent />
63
+ await runRoutePrefetches(api, override)
64
+
65
+ return (
66
+ <HydrateClient>
67
+ <PluginComponent />
68
+ </HydrateClient>
69
+ )
63
70
  }
@@ -1,5 +1,5 @@
1
- import ItemEditPage from '@/components/ItemEditPage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import ItemEditPage from '@/components/pages/item-edit-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
  type Params = Promise<{ section: string; itemId: string }>
4
4
  type SearchParams = Promise<{ locale?: string }>
5
5
 
@@ -2,15 +2,15 @@ import { Inter, Cairo } from 'next/font/google'
2
2
  import '../globals.css'
3
3
  import type { Metadata } from 'next'
4
4
  import { cn } from '@/lib/utils'
5
- import { ThemeProvider } from '@/components/ThemeProvider'
5
+ import { ThemeProvider } from '@/components/layout/theme-provider'
6
6
  import Providers from '@/app/providers'
7
7
  import auth from 'nextjs-cms/auth'
8
8
  import { getCMSConfig } from 'nextjs-cms/core'
9
9
  import { I18nProviderClient } from 'nextjs-cms/translations/client'
10
10
  import { resolveLanguage, RTL_LANGUAGES } from 'nextjs-cms/translations'
11
11
  import { getClientDictionaries } from 'nextjs-cms/translations/server'
12
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
13
- import Layout from '@/components/Layout'
12
+ import { api, HydrateClient } from '@/app/_trpc/server'
13
+ import Layout from '@/components/layout/layout'
14
14
  import { redirect } from 'next/navigation'
15
15
  import { DirectionProvider } from "@/components/ui/direction"
16
16
 
@@ -1,4 +1,4 @@
1
- import LoadingSpinners from '@/components/LoadingSpinners'
1
+ import LoadingSpinners from '@/components/feedback/loading-spinners'
2
2
 
3
3
  export default function Loading() {
4
4
  // You can add any UI inside Loading, including a Skeleton.
@@ -1,4 +1,4 @@
1
- import LogPage from '@/components/LogPage'
1
+ import LogPage from '@/components/pages/log-page'
2
2
 
3
3
  export const dynamic = 'force-dynamic'
4
4
 
@@ -1,5 +1,5 @@
1
- import NewPage from '@/components/NewPage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import NewPage from '@/components/pages/new-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
  type Params = Promise<{ section: string }>
4
4
 
5
5
  export default async function Page(props: { params: Params }) {
@@ -1,5 +1,5 @@
1
- import SectionPage from '@/components/SectionPage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import SectionPage from '@/components/pages/section-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
  type Params = Promise<{ section: string }>
4
4
  type SearchParams = Promise<{ locale?: string }>
5
5
 
@@ -1,5 +1,5 @@
1
- import SettingsPage from '@/components/SettingsPage'
2
- import { api, HydrateClient } from 'nextjs-cms/api/trpc/server'
1
+ import SettingsPage from '@/components/pages/settings-page'
2
+ import { api, HydrateClient } from '@/app/_trpc/server'
3
3
 
4
4
  export const dynamic = 'force-dynamic'
5
5
 
@@ -0,0 +1,6 @@
1
+ 'use client'
2
+
3
+ import { createNextjsCmsClient } from 'nextjs-cms/api/client'
4
+ import type { AppRouter } from './server'
5
+
6
+ export const { trpc, NextjsCmsProvider } = createNextjsCmsClient<AppRouter>()
@@ -0,0 +1,9 @@
1
+ import 'server-only'
2
+
3
+ import { createTRPCRouter } from 'nextjs-cms/api/server'
4
+
5
+ export const trpc = createTRPCRouter()
6
+
7
+ export type AppRouter = typeof trpc.appRouter
8
+
9
+ export const { api, HydrateClient } = trpc
@@ -0,0 +1,6 @@
1
+ import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server'
2
+
3
+ import type { AppRouter } from './server'
4
+
5
+ export type RouterInputs = inferRouterInputs<AppRouter>
6
+ export type RouterOutputs = inferRouterOutputs<AppRouter>
@@ -7,7 +7,7 @@ import { SectionFactory } from 'nextjs-cms/core/factories'
7
7
  import type { DocumentFieldConfigType } from 'nextjs-cms/core/fields'
8
8
  import auth from 'nextjs-cms/auth'
9
9
  import { sanitizeFileName, sanitizeFolderOrFileName } from 'nextjs-cms/utils'
10
- import { streamFile } from 'nextjs-cms/api/helpers'
10
+ import { streamFile } from 'nextjs-cms/api/server/actions'
11
11
  import { getCMSConfig } from 'nextjs-cms/core/config'
12
12
 
13
13
  /**
@@ -1,5 +1,5 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
- import { getPhoto } from 'nextjs-cms/api/helpers'
2
+ import { getPhoto } from 'nextjs-cms/api/server/actions'
3
3
 
4
4
  export async function GET(request: NextRequest) {
5
5
  const searchParams = request.nextUrl.searchParams
@@ -1,33 +1,3 @@
1
- import { fetchRequestHandler } from '@trpc/server/adapters/fetch'
2
- import { createTRPCContext, getAppRouter } from 'nextjs-cms/api'
3
- import { NextRequest } from 'next/server'
4
-
5
- /**
6
- * This wraps the `createContext` helper and provides the required context for the tRPC API when
7
- * handling a HTTP request (e.g. when you make requests from Client Components).
8
- */
9
-
10
- const context = async (req: NextRequest) => {
11
- return createTRPCContext({
12
- headers: req.headers,
13
- })
14
- }
15
-
16
- const handler = async (req: NextRequest) =>
17
- fetchRequestHandler({
18
- endpoint: '/api/trpc',
19
- req,
20
- router: await getAppRouter(),
21
- createContext: () => context(req),
22
- /*onError(opts) {
23
- return opts.error
24
- },*/
25
- onError:
26
- process.env.NODE_ENV === 'development'
27
- ? ({ path, error }) => {
28
- console.error(`❌ tRPC failed on ${path ?? '<no-path>'}: ${error.message}`)
29
- }
30
- : undefined,
31
- })
32
-
33
- export { handler as GET, handler as POST }
1
+ import { trpc } from '@/app/_trpc/server'
2
+
3
+ export const { GET, POST } = trpc.handler
@@ -7,7 +7,7 @@ import { SectionFactory } from 'nextjs-cms/core/factories'
7
7
  import type { VideoField } from 'nextjs-cms/core/fields'
8
8
  import auth from 'nextjs-cms/auth'
9
9
  import { sanitizeFileName, sanitizeFolderOrFileName } from 'nextjs-cms/utils'
10
- import { streamFile } from 'nextjs-cms/api/helpers'
10
+ import { streamFile } from 'nextjs-cms/api/server/actions'
11
11
  import { getCMSConfig } from 'nextjs-cms/core/config'
12
12
 
13
13
  /**
@@ -1,152 +1,20 @@
1
- 'use client'
2
-
3
- import { QueryClient, QueryClientProvider, defaultShouldDehydrateQuery } from '@tanstack/react-query'
4
- import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
5
- import { ModalProvider } from '@/context/ModalProvider'
6
- import { trpc } from '@/app/_trpc/client'
7
- import { httpBatchLink, loggerLink } from '@trpc/client'
8
- import SuperJSON from 'superjson'
9
- import { useState } from 'react'
10
- import { getCsrfToken, SessionProvider, refreshTokenLink } from 'nextjs-cms/auth/react'
11
- import { Session } from 'nextjs-cms/auth'
12
-
13
- function MakeTrpcClient() {
14
- const [trpcClient] = useState(() =>
15
- trpc.createClient({
16
- links: [
17
- /**
18
- * The refresh token link will automatically refresh the access token if it's expired.
19
- * It fetches the new access token using the refresh token by calling the `/api/auth/refresh` endpoint.
20
- */
21
- refreshTokenLink(),
22
- /**
23
- * The logger link will log all the operations that are being sent to the server.
24
- * @see https://trpc.io/docs/client/links/loggerLink
25
- */
26
- loggerLink({
27
- enabled: (op) =>
28
- process.env.NODE_ENV === 'development' ||
29
- (op.direction === 'down' && op.result instanceof Error),
30
- }),
31
-
32
- /**
33
- * The HTTP batch link is used to send multiple operations in a single HTTP request,
34
- * but doesn't wait for all the responses of the batch to be ready,
35
- * and streams the responses as soon as any data is available.
36
- * @see https://trpc.io/docs/client/links/httpBatchStreamLink
37
- *
38
- * TODO: The stream link is somehow causing empty responses before the actual response!
39
- */
40
- /*unstable_httpBatchStreamLink({
41
- transformer: superjson,
42
- url: '/api/trpc',
43
- // You can pass any HTTP headers you wish here
44
- async headers() {
45
- const headers = new Headers()
46
- headers.set('x-trpc-source', 'nextjs-react')
47
- headers.set('Authorization', `Bearer ${authStore.state.accessToken}`)
48
- return headers
49
- },
50
- }),*/
51
-
52
- /**
53
- * The HTTP batch link is used to send multiple operations in a single HTTP request.
54
- * @see https://trpc.io/docs/client/links/httpBatchLink
55
- */
56
- httpBatchLink({
57
- transformer: SuperJSON,
58
- url: '/api/trpc',
59
- // You can pass any HTTP headers you wish here
60
- async headers(op) {
61
- const headers = new Headers()
62
- /**
63
- * Check if there are any mutations in the operations list
64
- */
65
- if (op.opList.some((o) => o.type === 'mutation')) {
66
- /**
67
- * Get the CSRF token, and set it in the headers
68
- */
69
- const csrfToken = await getCsrfToken()
70
- headers.set('x-csrf-token', csrfToken)
71
- }
72
-
73
- headers.set('x-trpc-source', 'nextjs-react')
74
-
75
- return headers
76
- },
77
- }),
78
- ],
79
- }),
80
- )
81
-
82
- return trpcClient
83
- }
84
-
85
- function createQueryClient() {
86
- return new QueryClient({
87
- defaultOptions: {
88
- queries: {
89
- // With SSR, we usually want to set some default staleTime
90
- // above 0 to avoid refetching immediately on the client
91
- /**
92
- * It's better to leave the staleTime to 0 to always fetch the latest data in a cms
93
- */
94
- // staleTime: 3 * 1000,
95
- /**
96
- * We want to refetch on window focus in development only
97
- */
98
- refetchOnWindowFocus: process.env.NODE_ENV === 'development' ? true : false,
99
- retry: 1, // default: 3
100
- },
101
- dehydrate: {
102
- serializeData: SuperJSON.serialize,
103
- shouldDehydrateQuery: (query) => defaultShouldDehydrateQuery(query) || query.state.status === 'pending',
104
- },
105
- hydrate: {
106
- deserializeData: SuperJSON.deserialize,
107
- },
108
- },
109
- })
110
- }
111
-
112
- let browserQueryClient: QueryClient | undefined = undefined
113
-
114
- function getQueryClient() {
115
- if (typeof window === 'undefined') {
116
- // Server: always make a new query client
117
- return createQueryClient()
118
- } else {
119
- // Browser: make a new query client if we don't already have one
120
- // This is very important so we don't re-make a new client if React
121
- // suspends during the initial render. This may not be needed if we
122
- // have a suspense boundary BELOW the creation of the query client
123
- if (!browserQueryClient) browserQueryClient = createQueryClient()
124
- return browserQueryClient
125
- }
126
- }
127
-
128
- export default function Providers({ children, session }: { children: React.ReactNode; session: Session | undefined }) {
129
- // NOTE: Avoid useState when initializing the query client if you don't
130
- // have a suspense boundary between this and the code that may
131
- // suspend because React will throw away the client on the initial
132
- // render if it suspends and there is no boundary
133
- const queryClient = getQueryClient()
134
- // const trpcClient = getTrpcClient()
135
- const trpcClient = MakeTrpcClient()
136
-
137
- return (
138
- <QueryClientProvider client={queryClient}>
139
- <trpc.Provider client={trpcClient} queryClient={queryClient}>
140
- <SessionProvider
141
- session={session}
142
- refetchOnWindowFocus={false}
143
- refetchInterval={0}
144
- refetchWhenOffline={false}
145
- >
146
- <ModalProvider>{children}</ModalProvider>
147
- </SessionProvider>
148
- <ReactQueryDevtools initialIsOpen={false} />
149
- </trpc.Provider>
150
- </QueryClientProvider>
151
- )
152
- }
1
+ 'use client'
2
+
3
+ import type { Session } from 'nextjs-cms/auth'
4
+ import { NextjsCmsProvider } from '@/app/_trpc/client'
5
+ import { ModalProvider } from '@/components/feedback/modal-context'
6
+
7
+ export default function Providers({ children, session }: { children: React.ReactNode; session: Session | undefined }) {
8
+ return (
9
+ <NextjsCmsProvider
10
+ session={session}
11
+ sessionOptions={{
12
+ refetchOnWindowFocus: false,
13
+ refetchInterval: 0,
14
+ refetchWhenOffline: false,
15
+ }}
16
+ >
17
+ <ModalProvider>{children}</ModalProvider>
18
+ </NextjsCmsProvider>
19
+ )
20
+ }
@@ -1,5 +1,7 @@
1
- import { defineConfig } from 'nextjs-cms/core/config'
1
+ import { defineConfig } from 'nextjs-cms/core/config'
2
+ import process from 'process'
2
3
  import { resolve } from 'path'
4
+ import { env } from './env/env'
3
5
 
4
6
  export default defineConfig({
5
7
  ui: {
@@ -17,7 +19,7 @@ export default defineConfig({
17
19
  media: {
18
20
  upload: {
19
21
  path:
20
- process.env.NODE_ENV === 'development'
22
+ env.NODE_ENV === 'development'
21
23
  ? 'D:/Work/WebstormProjects/turbo-expo-next/apps/web/public/content/'
22
24
  : '/home2/syriasell/public_html/assets/content',
23
25
  preserveExtension: true,
@@ -1,8 +1,8 @@
1
1
  import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import React from 'react'
3
- import useModal from '@/hooks/useModal'
4
- import ProtectedImage from '@/components/ProtectedImage'
5
- import AdminEditPage from '@/components/AdminEditPage'
3
+ import { useModal } from '@/components/feedback/modal-context'
4
+ import ProtectedImage from '@/components/media/protected-image'
5
+ import AdminEditPage from '@/components/admin/admin-edit-page'
6
6
  import { useToast } from '@/components/ui/use-toast'
7
7
  import { ScrollArea } from '@/components/ui/scroll-area'
8
8
  import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
@@ -10,7 +10,7 @@ import { Badge } from '@/components/ui/badge'
10
10
  import { Button } from '@/components/ui/button'
11
11
  import { trpc } from '@/app/_trpc/client'
12
12
  import Image from 'next/image'
13
- import type { RouterOutputs } from 'nextjs-cms/api'
13
+ import type { RouterOutputs } from '@/app/_trpc/types'
14
14
  export default function AdminCard({
15
15
  admin,
16
16
  action,
@@ -1,9 +1,9 @@
1
1
  import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import React from 'react'
3
- import useModal from '@/hooks/useModal'
3
+ import { useModal } from '@/components/feedback/modal-context'
4
4
  import { trpc } from '@/app/_trpc/client'
5
- import AdminRoleCard from './AdminPrivilegeCard'
6
- import LoadingSpinners from './LoadingSpinners'
5
+ import AdminRoleCard from '@/components/admin/admin-privilege-card'
6
+ import LoadingSpinners from '@/components/feedback/loading-spinners'
7
7
  import { Button } from '@/components/ui/button'
8
8
 
9
9
  export default function AdminEditPage({ id, action }: { id: string; action: any }) {
@@ -5,7 +5,7 @@ import React, { useEffect } from 'react'
5
5
  import { useI18n } from 'nextjs-cms/translations/client'
6
6
  import { Badge } from '@/components/ui/badge'
7
7
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
8
- import type { RouterOutputs } from 'nextjs-cms/api'
8
+ import type { RouterOutputs } from '@/app/_trpc/types'
9
9
 
10
10
  export default function AdminRoleCard({
11
11
  privilege,