@nextsparkjs/core 0.1.0-beta.190 → 0.1.0-beta.191

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 (176) hide show
  1. package/dist/components/dashboard/block-editor/dynamic-form.d.ts.map +1 -1
  2. package/dist/components/dashboard/block-editor/dynamic-form.js +2 -2
  3. package/dist/components/dashboard/layouts/TopNavbar.js +1 -1
  4. package/dist/components/dashboard/mobile/MobileTopBar.js +3 -2
  5. package/dist/emails/otp-verification.d.ts.map +1 -1
  6. package/dist/emails/otp-verification.js +1 -1
  7. package/dist/emails/reset-password.d.ts.map +1 -1
  8. package/dist/emails/reset-password.js +1 -1
  9. package/dist/emails/team-invitation.d.ts.map +1 -1
  10. package/dist/emails/team-invitation.js +1 -1
  11. package/dist/emails/verify-email.d.ts.map +1 -1
  12. package/dist/emails/verify-email.js +1 -1
  13. package/dist/lib/actions/entity.actions.js +8 -8
  14. package/dist/lib/actions/team.actions.js +7 -7
  15. package/dist/lib/api/entity/generic-handler.js +5 -5
  16. package/dist/lib/api/permission-middleware.js +1 -1
  17. package/dist/lib/auth/registration-guard-plugin.d.ts.map +1 -1
  18. package/dist/lib/auth/registration-guard-plugin.js +2 -2
  19. package/dist/lib/auth-email-callbacks.d.ts +3 -1
  20. package/dist/lib/auth-email-callbacks.d.ts.map +1 -1
  21. package/dist/lib/auth-email-callbacks.js +8 -2
  22. package/dist/lib/auth.d.ts.map +1 -1
  23. package/dist/lib/auth.js +4 -3
  24. package/dist/lib/billing/gateways/stripe.js +1 -1
  25. package/dist/lib/entities/hooks.js +1 -1
  26. package/dist/templates/app/(auth)/accept-invite/[token]/page.tsx +1 -1
  27. package/dist/templates/app/(auth)/auth-error/page.tsx +1 -1
  28. package/dist/templates/app/(auth)/forgot-password/page.tsx +1 -1
  29. package/dist/templates/app/(auth)/layout.tsx +1 -1
  30. package/dist/templates/app/(auth)/login/page.tsx +1 -1
  31. package/dist/templates/app/(auth)/reset-password/page.tsx +1 -1
  32. package/dist/templates/app/(auth)/signup/page.tsx +1 -1
  33. package/dist/templates/app/(auth)/verify-email/page.tsx +1 -1
  34. package/dist/templates/app/(public)/[...slug]/page.tsx +3 -3
  35. package/dist/templates/app/(public)/layout.tsx +1 -1
  36. package/dist/templates/app/(public)/page.tsx +1 -1
  37. package/dist/templates/app/403/page.tsx +1 -1
  38. package/dist/templates/app/dashboard/(main)/[entity]/[id]/edit/page.tsx +1 -1
  39. package/dist/templates/app/dashboard/(main)/[entity]/[id]/page.tsx +4 -4
  40. package/dist/templates/app/dashboard/(main)/[entity]/create/page.tsx +1 -1
  41. package/dist/templates/app/dashboard/(main)/[entity]/loading.tsx +1 -1
  42. package/dist/templates/app/dashboard/(main)/[entity]/page.tsx +1 -1
  43. package/dist/templates/app/dashboard/(main)/layout.tsx +1 -1
  44. package/dist/templates/app/dashboard/(main)/loading.tsx +1 -1
  45. package/dist/templates/app/dashboard/(main)/media/page.tsx +1 -1
  46. package/dist/templates/app/dashboard/(main)/page.tsx +1 -1
  47. package/dist/templates/app/dashboard/(main)/patterns/[id]/edit/page.tsx +1 -1
  48. package/dist/templates/app/dashboard/(main)/patterns/[id]/page.tsx +1 -1
  49. package/dist/templates/app/dashboard/(main)/patterns/[id]/reports/page.tsx +1 -1
  50. package/dist/templates/app/dashboard/(main)/patterns/create/page.tsx +1 -1
  51. package/dist/templates/app/dashboard/(main)/patterns/page.tsx +1 -1
  52. package/dist/templates/app/dashboard/features/analytics/page.tsx +1 -1
  53. package/dist/templates/app/dashboard/features/automation/page.tsx +1 -1
  54. package/dist/templates/app/dashboard/features/layout.tsx +1 -1
  55. package/dist/templates/app/dashboard/features/loading.tsx +1 -1
  56. package/dist/templates/app/dashboard/features/webhooks/page.tsx +1 -1
  57. package/dist/templates/app/dashboard/layout.tsx +1 -1
  58. package/dist/templates/app/dashboard/permission-denied/page.tsx +1 -1
  59. package/dist/templates/app/dashboard/settings/api-keys/loading.tsx +1 -1
  60. package/dist/templates/app/dashboard/settings/api-keys/page.tsx +1 -1
  61. package/dist/templates/app/dashboard/settings/billing/loading.tsx +1 -1
  62. package/dist/templates/app/dashboard/settings/billing/page.tsx +1 -1
  63. package/dist/templates/app/dashboard/settings/invoices/[invoiceNumber]/page.tsx +1 -1
  64. package/dist/templates/app/dashboard/settings/invoices/loading.tsx +1 -1
  65. package/dist/templates/app/dashboard/settings/invoices/page.tsx +1 -1
  66. package/dist/templates/app/dashboard/settings/layout.tsx +1 -1
  67. package/dist/templates/app/dashboard/settings/loading.tsx +1 -1
  68. package/dist/templates/app/dashboard/settings/notifications/loading.tsx +1 -1
  69. package/dist/templates/app/dashboard/settings/notifications/page.tsx +1 -1
  70. package/dist/templates/app/dashboard/settings/page.tsx +1 -1
  71. package/dist/templates/app/dashboard/settings/password/loading.tsx +1 -1
  72. package/dist/templates/app/dashboard/settings/password/page.tsx +1 -1
  73. package/dist/templates/app/dashboard/settings/plans/loading.tsx +1 -1
  74. package/dist/templates/app/dashboard/settings/plans/page.tsx +1 -1
  75. package/dist/templates/app/dashboard/settings/profile/loading.tsx +1 -1
  76. package/dist/templates/app/dashboard/settings/profile/page.tsx +1 -1
  77. package/dist/templates/app/dashboard/settings/security/loading.tsx +1 -1
  78. package/dist/templates/app/dashboard/settings/security/page.tsx +1 -1
  79. package/dist/templates/app/dashboard/settings/teams/loading.tsx +1 -1
  80. package/dist/templates/app/dashboard/settings/teams/page.tsx +1 -1
  81. package/dist/templates/app/dashboard/settings/teams/permissions/page.tsx +1 -1
  82. package/dist/templates/app/devtools/api/[[...endpoint]]/page.tsx +1 -1
  83. package/dist/templates/app/devtools/config/page.tsx +1 -1
  84. package/dist/templates/app/devtools/layout.tsx +3 -2
  85. package/dist/templates/app/devtools/tests/[[...path]]/page.tsx +1 -1
  86. package/dist/templates/app/layout.ppr.tsx +1 -1
  87. package/dist/templates/app/layout.tsx +1 -1
  88. package/dist/templates/app/public/page.tsx +1 -1
  89. package/dist/templates/app/superadmin/layout.tsx +1 -1
  90. package/dist/templates/app/superadmin/page.tsx +1 -1
  91. package/dist/templates/app/superadmin/subscriptions/page.tsx +1 -1
  92. package/dist/templates/app/superadmin/team-roles/page.tsx +1 -1
  93. package/dist/templates/app/superadmin/teams/[teamId]/page.tsx +1 -1
  94. package/dist/templates/app/superadmin/teams/page.tsx +1 -1
  95. package/dist/templates/app/superadmin/users/[userId]/page.tsx +1 -1
  96. package/dist/templates/app/superadmin/users/page.tsx +1 -1
  97. package/package.json +11 -3
  98. package/scripts/build/registry/__tests__/template-registry.test.mjs +336 -2
  99. package/scripts/build/registry/__tests__/write-places.test.mjs +26 -0
  100. package/scripts/build/registry/generators/template-registry.mjs +202 -9
  101. package/scripts/build/registry/write-places.mjs +19 -5
  102. package/scripts/build/registry.mjs +53 -1
  103. package/templates/app/(auth)/accept-invite/[token]/page.tsx +1 -1
  104. package/templates/app/(auth)/auth-error/page.tsx +1 -1
  105. package/templates/app/(auth)/forgot-password/page.tsx +1 -1
  106. package/templates/app/(auth)/layout.tsx +1 -1
  107. package/templates/app/(auth)/login/page.tsx +1 -1
  108. package/templates/app/(auth)/reset-password/page.tsx +1 -1
  109. package/templates/app/(auth)/signup/page.tsx +1 -1
  110. package/templates/app/(auth)/verify-email/page.tsx +1 -1
  111. package/templates/app/(public)/[...slug]/page.tsx +3 -3
  112. package/templates/app/(public)/layout.tsx +1 -1
  113. package/templates/app/(public)/page.tsx +1 -1
  114. package/templates/app/403/page.tsx +1 -1
  115. package/templates/app/dashboard/(main)/[entity]/[id]/edit/page.tsx +1 -1
  116. package/templates/app/dashboard/(main)/[entity]/[id]/page.tsx +4 -4
  117. package/templates/app/dashboard/(main)/[entity]/create/page.tsx +1 -1
  118. package/templates/app/dashboard/(main)/[entity]/loading.tsx +1 -1
  119. package/templates/app/dashboard/(main)/[entity]/page.tsx +1 -1
  120. package/templates/app/dashboard/(main)/layout.tsx +1 -1
  121. package/templates/app/dashboard/(main)/loading.tsx +1 -1
  122. package/templates/app/dashboard/(main)/media/page.tsx +1 -1
  123. package/templates/app/dashboard/(main)/page.tsx +1 -1
  124. package/templates/app/dashboard/(main)/patterns/[id]/edit/page.tsx +1 -1
  125. package/templates/app/dashboard/(main)/patterns/[id]/page.tsx +1 -1
  126. package/templates/app/dashboard/(main)/patterns/[id]/reports/page.tsx +1 -1
  127. package/templates/app/dashboard/(main)/patterns/create/page.tsx +1 -1
  128. package/templates/app/dashboard/(main)/patterns/page.tsx +1 -1
  129. package/templates/app/dashboard/features/analytics/page.tsx +1 -1
  130. package/templates/app/dashboard/features/automation/page.tsx +1 -1
  131. package/templates/app/dashboard/features/layout.tsx +1 -1
  132. package/templates/app/dashboard/features/loading.tsx +1 -1
  133. package/templates/app/dashboard/features/webhooks/page.tsx +1 -1
  134. package/templates/app/dashboard/layout.tsx +1 -1
  135. package/templates/app/dashboard/permission-denied/page.tsx +1 -1
  136. package/templates/app/dashboard/settings/api-keys/loading.tsx +1 -1
  137. package/templates/app/dashboard/settings/api-keys/page.tsx +1 -1
  138. package/templates/app/dashboard/settings/billing/loading.tsx +1 -1
  139. package/templates/app/dashboard/settings/billing/page.tsx +1 -1
  140. package/templates/app/dashboard/settings/invoices/[invoiceNumber]/page.tsx +1 -1
  141. package/templates/app/dashboard/settings/invoices/loading.tsx +1 -1
  142. package/templates/app/dashboard/settings/invoices/page.tsx +1 -1
  143. package/templates/app/dashboard/settings/layout.tsx +1 -1
  144. package/templates/app/dashboard/settings/loading.tsx +1 -1
  145. package/templates/app/dashboard/settings/notifications/loading.tsx +1 -1
  146. package/templates/app/dashboard/settings/notifications/page.tsx +1 -1
  147. package/templates/app/dashboard/settings/page.tsx +1 -1
  148. package/templates/app/dashboard/settings/password/loading.tsx +1 -1
  149. package/templates/app/dashboard/settings/password/page.tsx +1 -1
  150. package/templates/app/dashboard/settings/plans/loading.tsx +1 -1
  151. package/templates/app/dashboard/settings/plans/page.tsx +1 -1
  152. package/templates/app/dashboard/settings/profile/loading.tsx +1 -1
  153. package/templates/app/dashboard/settings/profile/page.tsx +1 -1
  154. package/templates/app/dashboard/settings/security/loading.tsx +1 -1
  155. package/templates/app/dashboard/settings/security/page.tsx +1 -1
  156. package/templates/app/dashboard/settings/teams/loading.tsx +1 -1
  157. package/templates/app/dashboard/settings/teams/page.tsx +1 -1
  158. package/templates/app/dashboard/settings/teams/permissions/page.tsx +1 -1
  159. package/templates/app/devtools/api/[[...endpoint]]/page.tsx +1 -1
  160. package/templates/app/devtools/config/page.tsx +1 -1
  161. package/templates/app/devtools/layout.tsx +3 -2
  162. package/templates/app/devtools/tests/[[...path]]/page.tsx +1 -1
  163. package/templates/app/layout.ppr.tsx +1 -1
  164. package/templates/app/layout.tsx +1 -1
  165. package/templates/app/public/page.tsx +1 -1
  166. package/templates/app/superadmin/layout.tsx +1 -1
  167. package/templates/app/superadmin/page.tsx +1 -1
  168. package/templates/app/superadmin/subscriptions/page.tsx +1 -1
  169. package/templates/app/superadmin/team-roles/page.tsx +1 -1
  170. package/templates/app/superadmin/teams/[teamId]/page.tsx +1 -1
  171. package/templates/app/superadmin/teams/page.tsx +1 -1
  172. package/templates/app/superadmin/users/[userId]/page.tsx +1 -1
  173. package/templates/app/superadmin/users/page.tsx +1 -1
  174. package/tests/jest/__mocks__/@nextsparkjs/registries/template-scopes/client.ts +21 -0
  175. package/tests/jest/__mocks__/@nextsparkjs/registries/template-scopes/server.ts +23 -0
  176. package/tests/jest/__mocks__/next-intl-server.js +3 -3
@@ -34,6 +34,10 @@ const PLACES = [
34
34
  { path: '.nextspark/registries', kind: 'directory' },
35
35
  ]
36
36
 
37
+ // Registries are otherwise flat files. Route-scoped template registries are
38
+ // generated beneath this one owned subtree so their paths can mirror app/.
39
+ const TEMPLATE_SCOPES_DIRECTORY = '.nextspark/registries/template-scopes'
40
+
37
41
  /**
38
42
  * The directories the registry build removes old plugin route directories
39
43
  * under, from the project root, when app/api/v1/plugin is there: a symlink
@@ -86,9 +90,11 @@ function readable(projectRoot, dir) {
86
90
  * Report what is in the way under `dir`, from the project root, without going
87
91
  * through a symlink: each symlink, anything that is neither a file, a directory
88
92
  * nor a symlink, a directory that can't be read, and, with `filesOnly`, a
89
- * directory right under `dir`.
93
+ * directory right under `dir` unless it is one of `directoryExceptions`.
94
+ * An exception is still walked with the same symlink guard; it is not a
95
+ * blanket exemption for arbitrary registry subtrees.
90
96
  */
91
- function reportEntriesUnder(projectRoot, dir, filesOnly, report) {
97
+ function reportEntriesUnder(projectRoot, dir, filesOnly, report, directoryExceptions = new Set()) {
92
98
  let entries
93
99
  try {
94
100
  entries = readdirSync(join(projectRoot, dir), { withFileTypes: true })
@@ -101,8 +107,10 @@ function reportEntriesUnder(projectRoot, dir, filesOnly, report) {
101
107
  if (entry.isSymbolicLink()) {
102
108
  report(path, 'is a symlink')
103
109
  } else if (entry.isDirectory()) {
104
- if (filesOnly) report(path, 'is not a file')
105
- else reportEntriesUnder(projectRoot, path, false, report)
110
+ if (filesOnly && !directoryExceptions.has(path)) report(path, 'is not a file')
111
+ else reportEntriesUnder(projectRoot, path, false, report, directoryExceptions)
112
+ } else if (entry.isFile() && directoryExceptions.has(path)) {
113
+ report(path, 'is not a directory')
106
114
  } else if (!entry.isFile()) {
107
115
  report(path, 'is neither a file nor a directory')
108
116
  }
@@ -206,7 +214,13 @@ export function unsafeWritePlaces(projectRoot, written = [], { activeTheme = pro
206
214
  reportEntriesUnder(projectRoot, 'app/(templates)', false, report)
207
215
  }
208
216
  if (!reported('.nextspark') && !reported('.nextspark/registries')) {
209
- reportEntriesUnder(projectRoot, '.nextspark/registries', true, report)
217
+ reportEntriesUnder(
218
+ projectRoot,
219
+ '.nextspark/registries',
220
+ true,
221
+ report,
222
+ new Set([TEMPLATE_SCOPES_DIRECTORY])
223
+ )
210
224
  }
211
225
  return unsafe
212
226
  }
@@ -21,6 +21,7 @@ import '../utils/console-guard.mjs'
21
21
  import { join, dirname, resolve } from 'path'
22
22
  import { fileURLToPath } from 'url'
23
23
  import { existsSync } from 'fs'
24
+ import { lstat, readdir, readFile } from 'fs/promises'
24
25
  import dotenv from 'dotenv'
25
26
 
26
27
  // Load .env from the correct project root
@@ -67,7 +68,12 @@ import { generatePluginRegistry, generatePluginRegistryClient } from './registry
67
68
  import { generateEntityRegistry, generateEntityRegistryClient } from './registry/generators/entity-registry.mjs'
68
69
  import { generateEntityTypes } from './registry/generators/entity-types.mjs'
69
70
  import { generateThemeRegistry } from './registry/generators/theme-registry.mjs'
70
- import { generateTemplateRegistry, generateTemplateRegistryClient } from './registry/generators/template-registry.mjs'
71
+ import {
72
+ generateTemplateRegistry,
73
+ generateTemplateRegistryClient,
74
+ generateTemplateScopeRegistries,
75
+ SCOPE_MARKER
76
+ } from './registry/generators/template-registry.mjs'
71
77
  import { generateEmailRegistry } from './registry/generators/email-registry.mjs'
72
78
  import { generateBlockRegistry, generateBlockRegistryClient, generateBlockRegistryLazy } from './registry/generators/block-registry.mjs'
73
79
  import { generateIconRegistry } from './registry/generators/icon-registry.mjs'
@@ -160,6 +166,52 @@ async function generateRegistryFiles(CONFIG, plugins, entities, themes, template
160
166
  log(`${file.name}`, 'success')
161
167
  }
162
168
 
169
+ // Each route imports its own tiny registry rather than the global one.
170
+ // Build a complete replacement before cleanup so a theme change can never
171
+ // leave an existing route pointing at an old component import.
172
+ const templateScopes = await generateTemplateScopeRegistries(templates, CONFIG, templateAnalysis)
173
+ await files.mkdir(templateScopes.directory, { recursive: true })
174
+ const generated = new Set(templateScopes.files.map(file => file.path))
175
+
176
+ async function removeStaleScopedFiles(directory) {
177
+ let entries
178
+ try {
179
+ entries = await readdir(directory, { withFileTypes: true })
180
+ } catch (error) {
181
+ if (error?.code === 'ENOENT') return
182
+ throw error
183
+ }
184
+ for (const entry of entries) {
185
+ const path = join(directory, entry.name)
186
+ const stat = await lstat(path)
187
+ if (stat.isSymbolicLink()) continue
188
+ if (stat.isDirectory()) {
189
+ await removeStaleScopedFiles(path)
190
+ continue
191
+ }
192
+ if (!stat.isFile() || generated.has(path) || !path.endsWith('.ts')) continue
193
+ // Only files bearing our explicit marker are owned by this generator.
194
+ if ((await readFile(path, 'utf8')).includes(SCOPE_MARKER)) await files.rm(path, { force: true })
195
+ }
196
+ if (directory !== templateScopes.directory) {
197
+ try {
198
+ const remaining = await readdir(directory)
199
+ if (remaining.length === 0) {
200
+ await files.rmdir(directory)
201
+ }
202
+ } catch {
203
+ // Ignore if directory disappeared or cannot be removed
204
+ }
205
+ }
206
+ }
207
+
208
+ await removeStaleScopedFiles(templateScopes.directory)
209
+ for (const file of templateScopes.files) {
210
+ await files.mkdir(dirname(file.path), { recursive: true })
211
+ await files.writeFile(file.path, file.content, 'utf8')
212
+ }
213
+ log(`template-scopes (${templateScopes.files.length / 2})`, 'success')
214
+
163
215
  } catch (error) {
164
216
  logFailure('Error writing registry files', error)
165
217
  process.exit(1)
@@ -9,7 +9,7 @@ import { Loader2, CheckCircle, XCircle, Users, LogIn, UserPlus } from 'lucide-re
9
9
  import { toast } from 'sonner'
10
10
  import Link from 'next/link'
11
11
  import { sel } from '@nextsparkjs/core/selectors'
12
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
12
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/(auth)/accept-invite/[token]/page'
13
13
  import { withBasePath } from '@nextsparkjs/core/lib/base-path'
14
14
 
15
15
  type InvitationStatus = 'loading' | 'valid' | 'accepting' | 'accepted' | 'error' | 'expired' | 'not_found' | 'email_mismatch' | 'already_member' | 'requires_auth'
@@ -1,7 +1,7 @@
1
1
  import type { Metadata } from 'next'
2
2
  import { Suspense } from 'react'
3
3
  import { AuthErrorPage } from '@nextsparkjs/core/components/auth/pages/AuthErrorPage'
4
- import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/core/lib/template-resolver'
4
+ import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/registries/template-scopes/server/(auth)/auth-error/page'
5
5
 
6
6
  const defaultMetadata: Metadata = {
7
7
  title: 'Authentication Error',
@@ -14,7 +14,7 @@ import { Input } from '@nextsparkjs/core/components/ui/input';
14
14
  import { Label } from '@nextsparkjs/core/components/ui/label';
15
15
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert';
16
16
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nextsparkjs/core/components/ui/card';
17
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/(auth)/forgot-password/page'
18
18
 
19
19
 
20
20
  function ForgotPasswordPage() {
@@ -1,7 +1,7 @@
1
1
  import { Suspense } from 'react'
2
2
  import type { Metadata } from 'next'
3
3
  import { AuthWrapper } from '@nextsparkjs/core/components/auth/layouts/AuthWrapper'
4
- import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/core/lib/template-resolver'
4
+ import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/registries/template-scopes/server/(auth)/layout'
5
5
 
6
6
  const defaultMetadata: Metadata = {
7
7
  title: {
@@ -1,6 +1,6 @@
1
1
  import type { Metadata } from 'next'
2
2
  import { LoginForm } from '@nextsparkjs/core/components/auth/forms/LoginForm'
3
- import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/core/lib/template-resolver'
3
+ import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/registries/template-scopes/server/(auth)/login/page'
4
4
 
5
5
  export const dynamic = 'force-dynamic'
6
6
 
@@ -18,7 +18,7 @@ import { Label } from "@nextsparkjs/core/components/ui/label";
18
18
  import { PasswordInput } from "@nextsparkjs/core/components/ui/password-input";
19
19
  import { Alert, AlertDescription } from "@nextsparkjs/core/components/ui/alert";
20
20
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@nextsparkjs/core/components/ui/card";
21
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
21
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/(auth)/reset-password/page'
22
22
  import { sel } from '@nextsparkjs/core/selectors'
23
23
 
24
24
  function ResetPasswordContent() {
@@ -2,7 +2,7 @@ import { Suspense } from 'react'
2
2
  import type { Metadata } from 'next'
3
3
  import { redirect } from 'next/navigation'
4
4
  import { SignupForm } from '@nextsparkjs/core/components/auth/forms/SignupForm'
5
- import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/core/lib/template-resolver'
5
+ import { getTemplateOrDefault, getMetadataOrDefault } from '@nextsparkjs/registries/template-scopes/server/(auth)/signup/page'
6
6
  import { AUTH_CONFIG } from '@nextsparkjs/core/lib/config'
7
7
  import { resolveAuthMethods } from '@nextsparkjs/core/lib/auth/auth-methods'
8
8
  import { TeamService } from '@nextsparkjs/core/lib/services'
@@ -5,7 +5,7 @@ import { useSearchParams, useRouter } from "next/navigation";
5
5
  import { Suspense, useEffect, useState } from "react";
6
6
  import { Button } from '@nextsparkjs/core/components/ui/button';
7
7
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert';
8
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
8
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/(auth)/verify-email/page'
9
9
  import { sel } from '@nextsparkjs/core/selectors'
10
10
  import { withBasePath } from '@nextsparkjs/core/lib/base-path'
11
11
 
@@ -21,7 +21,7 @@ import {
21
21
  getEntityBasePath,
22
22
  } from '@nextsparkjs/core/lib/entities/schema-generator'
23
23
  import { getEntityRegistry, setEntityRegistry } from '@nextsparkjs/core/lib/entities/queries'
24
- import { TemplateService } from '@nextsparkjs/core/lib/services/template.service'
24
+ import { hasTemplateOverride, getTemplateComponent } from '@nextsparkjs/registries/template-scopes/server/(public)/[...slug]/page'
25
25
  import { resolvePublicEntityFromUrl } from '@nextsparkjs/core/lib/api/entity/public-resolver'
26
26
  import { PublicEntityGrid } from '@nextsparkjs/core/components/public/entities/PublicEntityGrid'
27
27
  import type { EntityConfig } from '@nextsparkjs/core/lib/entities/types'
@@ -307,8 +307,8 @@ export default async function DynamicPublicPage({
307
307
  // === SINGLE ITEM PAGE ===
308
308
  // Check for theme template override first
309
309
  const templatePath = buildTemplatePath(entity)
310
- if (TemplateService.hasOverride(templatePath)) {
311
- const Template = TemplateService.getComponent(templatePath)
310
+ if (hasTemplateOverride(templatePath)) {
311
+ const Template = getTemplateComponent(templatePath)
312
312
  if (Template) {
313
313
  // Template handles its own data fetching and rendering
314
314
  // Pass params in the format expected by the template
@@ -2,7 +2,7 @@ import { Suspense } from "react"
2
2
  import type { Metadata } from "next"
3
3
  import { PublicNavbar } from '@nextsparkjs/core/components/app/layouts/PublicNavbar'
4
4
  import { PublicFooter } from '@nextsparkjs/core/components/app/layouts/PublicFooter'
5
- import { getTemplateOrDefault, getMetadataOrDefault } from "@nextsparkjs/core/lib/template-resolver"
5
+ import { getTemplateOrDefault, getMetadataOrDefault } from "@nextsparkjs/registries/template-scopes/server/(public)/layout"
6
6
 
7
7
  // ✅ MINIMAL GENERIC METADATA (cliente puede override con template)
8
8
  const defaultMetadata: Metadata = {
@@ -1,5 +1,5 @@
1
1
  import { redirect } from 'next/navigation'
2
- import { getTemplateOrDefault } from "@nextsparkjs/core/lib/template-resolver"
2
+ import { getTemplateOrDefault } from "@nextsparkjs/registries/template-scopes/server/(public)/page"
3
3
 
4
4
  /**
5
5
  * Default Public Home Page (CORE)
@@ -6,7 +6,7 @@ import { useSearchParams } from 'next/navigation'
6
6
  import { Suspense } from 'react'
7
7
  import { Button } from '@nextsparkjs/core/components/ui/button'
8
8
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nextsparkjs/core/components/ui/card'
9
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
9
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/403/page'
10
10
 
11
11
  function ForbiddenContent() {
12
12
  const searchParams = useSearchParams()!
@@ -6,7 +6,7 @@ import { useEffect, useState } from 'react'
6
6
  import { clientEntityRegistry, ensureClientInitialized, type ClientEntityConfig } from '@nextsparkjs/registries/entity-registry.client'
7
7
  import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityFormWrapper'
8
8
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
9
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
9
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/[entity]/[id]/edit/page'
10
10
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
11
11
 
12
12
  function EntityEditPage() {
@@ -2,7 +2,7 @@ import { notFound, redirect } from 'next/navigation'
2
2
  import { getEntity, getEntityRegistry, getChildEntities, setEntityRegistry } from '@nextsparkjs/core/lib/entities/queries'
3
3
  import { EntityDetailWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityDetailWrapper'
4
4
  import type { Metadata } from 'next'
5
- import { TemplateService } from '@nextsparkjs/core/lib/services/template.service'
5
+ import { hasTemplateOverride, getTemplateComponent } from '@nextsparkjs/registries/template-scopes/server/dashboard/(main)/[entity]/[id]/page'
6
6
  import type { EntityConfig, ChildEntityDefinition } from '@nextsparkjs/core/lib/entities/types'
7
7
  // Import registry directly - webpack resolves @nextsparkjs/registries alias at compile time
8
8
  import { ENTITY_REGISTRY, ENTITY_METADATA } from '@nextsparkjs/registries/entity-registry'
@@ -29,8 +29,8 @@ async function EntityDetailPage({ params }: PageProps) {
29
29
  // Check if there's a specific template override for this entity
30
30
  // e.g., app/dashboard/(main)/boards/[id]/page.tsx for boards
31
31
  const specificTemplatePath = `app/dashboard/(main)/${entitySlug}/[id]/page.tsx`
32
- if (TemplateService.hasOverride(specificTemplatePath)) {
33
- const OverrideComponent = TemplateService.getComponent(specificTemplatePath)
32
+ if (hasTemplateOverride(specificTemplatePath)) {
33
+ const OverrideComponent = getTemplateComponent(specificTemplatePath)
34
34
  if (OverrideComponent) {
35
35
  console.log(`🎨 Entity-specific template override applied for ${specificTemplatePath}`)
36
36
  return <OverrideComponent params={params} />
@@ -82,4 +82,4 @@ export const metadata: Metadata = {
82
82
  description: 'View entity details'
83
83
  }
84
84
 
85
- export default EntityDetailPage
85
+ export default EntityDetailPage
@@ -6,7 +6,7 @@ import { useEffect, useState } from 'react'
6
6
  import { clientEntityRegistry, ensureClientInitialized, type ClientEntityConfig } from '@nextsparkjs/registries/entity-registry.client'
7
7
  import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityFormWrapper'
8
8
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
9
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
9
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/[entity]/create/page'
10
10
 
11
11
  function EntityCreatePage() {
12
12
  const params = useParams()!
@@ -1,5 +1,5 @@
1
1
  import { Skeleton } from '@nextsparkjs/core/components/ui/skeleton'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/(main)/[entity]/loading'
3
3
 
4
4
  function EntityLoading() {
5
5
  return (
@@ -2,7 +2,7 @@ import { notFound } from 'next/navigation'
2
2
  import { getEntity, getEntityRegistry, setEntityRegistry } from '@nextsparkjs/core/lib/entities/queries'
3
3
  import { EntityListWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityListWrapper'
4
4
  import type { Metadata } from 'next'
5
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
5
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/(main)/[entity]/page'
6
6
  import type { EntityConfig, ChildEntityDefinition } from '@nextsparkjs/core/lib/entities/types'
7
7
  // Import registry directly - webpack resolves @nextsparkjs/registries alias at compile time
8
8
  import { ENTITY_REGISTRY, ENTITY_METADATA } from '@nextsparkjs/registries/entity-registry'
@@ -14,7 +14,7 @@ import { redirect } from 'next/navigation'
14
14
  import { DashboardShell } from '@nextsparkjs/core/components/dashboard/layouts/DashboardShell'
15
15
  import { serializeEntityConfig, type SerializableEntityConfig } from '@nextsparkjs/core/lib/entities/serialization'
16
16
  import { setEntityRegistry } from '@nextsparkjs/core/lib/entities/queries'
17
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
17
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/(main)/layout'
18
18
  import type { EntityConfig, ChildEntityDefinition } from '@nextsparkjs/core/lib/entities/types'
19
19
  import { checkPermission } from '@nextsparkjs/core/lib/permissions/check'
20
20
  import { getDashboardTeamId } from '@nextsparkjs/core/lib/teams/dashboard-team'
@@ -1,5 +1,5 @@
1
1
  import { SkeletonDashboardHome } from '@nextsparkjs/core/components/ui/skeleton-dashboard'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/(main)/loading'
3
3
 
4
4
  function DashboardLoading() {
5
5
  return <SkeletonDashboardHome />
@@ -48,7 +48,7 @@ import { useDebounce } from '@nextsparkjs/core/hooks/useDebounce'
48
48
  import { useToast } from '@nextsparkjs/core/hooks/useToast'
49
49
  import { sel } from '@nextsparkjs/core/lib/selectors'
50
50
  import { usePermissions } from '@nextsparkjs/core/lib/permissions/hooks'
51
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
51
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/media/page'
52
52
  import type { Media, MediaListOptions } from '@nextsparkjs/core/lib/media/types'
53
53
  import type { Permission } from '@nextsparkjs/core/lib/permissions/types'
54
54
  import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
@@ -7,7 +7,7 @@ import { Button } from '@nextsparkjs/core/components/ui/button'
7
7
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nextsparkjs/core/components/ui/card'
8
8
  import { Badge } from '@nextsparkjs/core/components/ui/badge'
9
9
  import { useTranslations } from 'next-intl'
10
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
10
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/page'
11
11
 
12
12
  import {
13
13
  Loader2,
@@ -14,7 +14,7 @@ import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrapper
14
14
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
15
15
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert'
16
16
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
17
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/patterns/[id]/edit/page'
18
18
 
19
19
  function PatternEditPage() {
20
20
  const params = useParams()!
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { redirect } from 'next/navigation'
8
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
8
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/(main)/patterns/[id]/page'
9
9
 
10
10
  interface PageProps {
11
11
  params: Promise<{
@@ -17,7 +17,7 @@ import { Button } from '@nextsparkjs/core/components/ui/button'
17
17
  import { Alert, AlertDescription, AlertTitle } from '@nextsparkjs/core/components/ui/alert'
18
18
  import { Skeleton } from '@nextsparkjs/core/components/ui/skeleton'
19
19
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
20
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
20
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/patterns/[id]/reports/page'
21
21
 
22
22
  interface PatternData {
23
23
  id: string
@@ -12,7 +12,7 @@ import { clientEntityRegistry, ensureClientInitialized, type ClientEntityConfig
12
12
  import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityFormWrapper'
13
13
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
14
14
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert'
15
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
15
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/patterns/create/page'
16
16
 
17
17
  function PatternsCreatePage() {
18
18
  const router = useRouter()
@@ -28,7 +28,7 @@ import type { Permission } from '@nextsparkjs/core/lib/permissions/types'
28
28
  import type { QuickAction, DropdownAction } from '@nextsparkjs/core/components/entities/entity-table.types'
29
29
  import { sel } from '@nextsparkjs/core/lib/test'
30
30
  import { toast } from 'sonner'
31
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
31
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/(main)/patterns/page'
32
32
 
33
33
  interface PatternItem {
34
34
  id: string
@@ -4,7 +4,7 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { BarChart3 } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/features/analytics/page'
8
8
 
9
9
  function AdvancedAnalyticsPage() {
10
10
  const t = useTranslations('features')
@@ -4,7 +4,7 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { Zap } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/features/automation/page'
8
8
 
9
9
  function TaskAutomationPage() {
10
10
  const t = useTranslations('features')
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from 'react'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/features/layout'
3
3
 
4
4
  interface FeaturesLayoutProps {
5
5
  children: ReactNode
@@ -1,5 +1,5 @@
1
1
  import { SkeletonFeaturePlaceholder } from '@nextsparkjs/core/components/ui/skeleton-features'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/features/loading'
3
3
 
4
4
  function FeaturesLoading() {
5
5
  return <SkeletonFeaturePlaceholder />
@@ -4,7 +4,7 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { Webhook } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/features/webhooks/page'
8
8
 
9
9
  function WebhooksPage() {
10
10
  const t = useTranslations('features')
@@ -59,7 +59,7 @@ function DashboardLayoutContent({ children }: { children: React.ReactNode }) {
59
59
  Children run within authenticated boundary -
60
60
  nested layouts CAN be themed but security is guaranteed
61
61
  */}
62
- <div key="dashboard-children" data-cy="dashboard-container">{children}</div>
62
+ <div key="dashboard-children" id="dashboard-container" data-cy="dashboard-container" data-testid="dashboard-container">{children}</div>
63
63
  </>
64
64
  )
65
65
  }
@@ -5,7 +5,7 @@
5
5
  * This page is displayed when a user attempts to access a resource they don't have permission for.
6
6
  */
7
7
  import { NoPermission } from '@nextsparkjs/core/components/permissions/NoPermission'
8
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
8
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/permission-denied/page'
9
9
 
10
10
  interface PermissionDeniedPageProps {
11
11
  searchParams: Promise<{
@@ -1,5 +1,5 @@
1
1
  import { SkeletonApiKeysPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/settings/api-keys/loading'
3
3
 
4
4
  function ApiKeysLoading() {
5
5
  return <SkeletonApiKeysPage />
@@ -35,7 +35,7 @@ import {
35
35
  import { CreateApiKeyDialog } from '@nextsparkjs/core/components/api/keys/CreateApiKeyDialog';
36
36
  import { ApiKeyDisplay } from '@nextsparkjs/core/components/api/keys/ApiKeyDisplay';
37
37
  import { toast } from 'sonner';
38
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
38
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/api-keys/page'
39
39
  import { sel } from '@nextsparkjs/core/selectors'
40
40
  import { withBasePath } from '@nextsparkjs/core/lib/base-path'
41
41
 
@@ -1,5 +1,5 @@
1
1
  import { SkeletonBillingPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/settings/billing/loading'
3
3
 
4
4
  function BillingLoading() {
5
5
  return <SkeletonBillingPage />
@@ -16,7 +16,7 @@ import {
16
16
  } from 'lucide-react'
17
17
  import { sel } from '@nextsparkjs/core/selectors'
18
18
  import { useTranslations } from 'next-intl'
19
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
19
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/billing/page'
20
20
  import { useInvoices } from '@nextsparkjs/core/hooks/useInvoices'
21
21
  import { useSubscription } from '@nextsparkjs/core/hooks/useSubscription'
22
22
  import { InvoicesTable } from '@nextsparkjs/core/components/billing'
@@ -7,7 +7,7 @@ import { Button } from '@nextsparkjs/core/components/ui/button'
7
7
  import { Separator } from '@nextsparkjs/core/components/ui/separator'
8
8
  import { ArrowLeft, Printer, Loader2 } from 'lucide-react'
9
9
  import { useTranslations } from 'next-intl'
10
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
10
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/invoices/[invoiceNumber]/page'
11
11
  import { useInvoice } from '@nextsparkjs/core/hooks/useInvoice'
12
12
  import { useTeam } from '@nextsparkjs/core/hooks/useTeam'
13
13
  import { InvoiceStatusBadge } from '@nextsparkjs/core/components/billing/InvoiceStatusBadge'
@@ -1,5 +1,5 @@
1
1
  import { SkeletonInvoicesPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/settings/invoices/loading'
3
3
 
4
4
  function InvoicesLoading() {
5
5
  return <SkeletonInvoicesPage />
@@ -5,7 +5,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@next
5
5
  import { Button } from '@nextsparkjs/core/components/ui/button'
6
6
  import { Calendar } from 'lucide-react'
7
7
  import { useTranslations } from 'next-intl'
8
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
8
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/invoices/page'
9
9
  import { useInvoices } from '@nextsparkjs/core/hooks/useInvoices'
10
10
  import { InvoicesTable } from '@nextsparkjs/core/components/billing'
11
11
 
@@ -11,7 +11,7 @@ import { ArrowLeft } from 'lucide-react'
11
11
  import { useState, useCallback, useEffect } from 'react'
12
12
  import { sel } from '@nextsparkjs/core/selectors'
13
13
  import { useTranslations } from 'next-intl'
14
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
14
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/layout'
15
15
  import { isSettingsPageEnabled } from '@nextsparkjs/core/lib/config/config-sync'
16
16
 
17
17
  /**
@@ -1,5 +1,5 @@
1
1
  import { SkeletonSettingsOverview } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/settings/loading'
3
3
 
4
4
  function SettingsLoading() {
5
5
  return <SkeletonSettingsOverview />
@@ -1,5 +1,5 @@
1
1
  import { SkeletonNotificationsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
- import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/registries/template-scopes/server/dashboard/settings/notifications/loading'
3
3
 
4
4
  function NotificationsLoading() {
5
5
  return <SkeletonNotificationsPage />
@@ -20,7 +20,7 @@ import { sel } from '@nextsparkjs/core/selectors'
20
20
  import { useTranslations } from 'next-intl'
21
21
  import { useUserWithMetaSettings } from '@nextsparkjs/core/hooks/useUserSettings'
22
22
  import { NotificationsPageSkeleton } from '@nextsparkjs/core/components/settings/SettingsPageSkeleton'
23
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
23
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/notifications/page'
24
24
 
25
25
  function NotificationsPage() {
26
26
  const t = useTranslations('settings')
@@ -14,7 +14,7 @@ import {
14
14
  Key,
15
15
  type LucideIcon
16
16
  } from 'lucide-react'
17
- import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-scopes/client/dashboard/settings/page'
18
18
 
19
19
  // Icon mapping for settings pages
20
20
  const SETTINGS_ICONS: Record<string, LucideIcon> = {