bsmnt 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/templates/next-pagebuilder/app/(content)/[[...slug]]/page.tsx +17 -8
- package/src/templates/next-pagebuilder/app/(content)/layout.tsx +19 -7
- package/src/templates/next-pagebuilder/app/actions/refresh.ts +5 -0
- package/src/templates/next-pagebuilder/components/layout/footer/index.tsx +15 -19
- package/src/templates/next-pagebuilder/components/layout/header/index.tsx +3 -5
- package/src/templates/next-pagebuilder/components/layout/json-ld/index.tsx +11 -10
- package/src/templates/next-pagebuilder/components/layout/wrapper/index.tsx +14 -4
- package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/content-card.tsx +3 -5
- package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/content-filters.tsx +93 -0
- package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/content-grid.tsx +7 -9
- package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/content-pagination-nav.tsx +71 -0
- package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/index.tsx +212 -0
- package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/types.ts +5 -4
- package/src/templates/next-pagebuilder/components/page-builder/renderer.tsx +13 -5
- package/src/templates/next-pagebuilder/components/page-document/index.tsx +9 -4
- package/src/templates/next-pagebuilder/components/sanity/visual-editing.tsx +2 -1
- package/src/templates/next-pagebuilder/lib/integrations/sanity/constants.ts +1 -0
- package/src/templates/next-pagebuilder/lib/integrations/sanity/fetchers/layout.ts +17 -18
- package/src/templates/next-pagebuilder/lib/integrations/sanity/live/index.tsx +29 -2
- package/src/templates/next-pagebuilder/lib/integrations/sanity/presentation.ts +118 -0
- package/src/templates/next-pagebuilder/lib/integrations/sanity/queries.ts +144 -31
- package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.config.ts +5 -100
- package/src/templates/next-pagebuilder/next.config.ts +3 -0
- package/src/templates/next-pagebuilder/package.json +1 -2
- package/src/templates/next-pagebuilder/components/page-builder/components/post-collection/index.tsx +0 -28
|
@@ -97,6 +97,13 @@ const pageProjection = `
|
|
|
97
97
|
_updatedAt
|
|
98
98
|
`
|
|
99
99
|
|
|
100
|
+
const pageMetadataProjection = `
|
|
101
|
+
_id,
|
|
102
|
+
title,
|
|
103
|
+
metadata,
|
|
104
|
+
_updatedAt
|
|
105
|
+
`
|
|
106
|
+
|
|
100
107
|
export const PAGE_QUERY = defineQuery(`
|
|
101
108
|
*[
|
|
102
109
|
_type == "page" &&
|
|
@@ -109,6 +116,18 @@ export const PAGE_QUERY = defineQuery(`
|
|
|
109
116
|
}
|
|
110
117
|
`)
|
|
111
118
|
|
|
119
|
+
export const PAGE_METADATA_QUERY = defineQuery(`
|
|
120
|
+
*[
|
|
121
|
+
_type == "page" &&
|
|
122
|
+
(
|
|
123
|
+
($slug == null && !defined(pageFolder._ref) && (!defined(slug.current) || slug.current == "" || slug.current == "/")) ||
|
|
124
|
+
${pageResolvedSlugExpression} == $slug
|
|
125
|
+
)
|
|
126
|
+
][0] {
|
|
127
|
+
${pageMetadataProjection}
|
|
128
|
+
}
|
|
129
|
+
`)
|
|
130
|
+
|
|
112
131
|
export const ALL_PAGE_SLUGS_QUERY = defineQuery(`
|
|
113
132
|
*[_type == "page" && (defined(pageFolder->slug.current) || defined(slug.current))] | order(title asc) {
|
|
114
133
|
title,
|
|
@@ -193,6 +212,68 @@ export const ALL_BLOG_ARTICLES_QUERY = defineQuery(`
|
|
|
193
212
|
}
|
|
194
213
|
`)
|
|
195
214
|
|
|
215
|
+
export const BLOG_ARTICLES_PAGINATED_QUERY = defineQuery(`
|
|
216
|
+
*[
|
|
217
|
+
_type == "page" &&
|
|
218
|
+
pageFolder->slug.current == "blog" &&
|
|
219
|
+
defined(slug.current) &&
|
|
220
|
+
slug.current != "" &&
|
|
221
|
+
slug.current != "/" &&
|
|
222
|
+
(
|
|
223
|
+
!defined($category) ||
|
|
224
|
+
$category == "" ||
|
|
225
|
+
$category in pageBuilder[_ref in *[_type == "blogContent"]._id][0]->categories[]->slug.current
|
|
226
|
+
)
|
|
227
|
+
] | order(_updatedAt desc)[$offset...$offset + $limit] {
|
|
228
|
+
_id,
|
|
229
|
+
title,
|
|
230
|
+
"slug": slug,
|
|
231
|
+
"resolvedSlug": ${pageResolvedSlugExpression},
|
|
232
|
+
"blogContent": pageBuilder[_ref in *[_type == "blogContent"]._id][0]->{
|
|
233
|
+
thumbnail{
|
|
234
|
+
...,
|
|
235
|
+
alt
|
|
236
|
+
},
|
|
237
|
+
categories[]->{
|
|
238
|
+
_id,
|
|
239
|
+
title,
|
|
240
|
+
slug
|
|
241
|
+
},
|
|
242
|
+
date,
|
|
243
|
+
author->{
|
|
244
|
+
_id,
|
|
245
|
+
name,
|
|
246
|
+
avatar
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
metadata,
|
|
250
|
+
_updatedAt
|
|
251
|
+
}
|
|
252
|
+
`)
|
|
253
|
+
|
|
254
|
+
export const BLOG_ARTICLES_COUNT_QUERY = defineQuery(`
|
|
255
|
+
count(*[
|
|
256
|
+
_type == "page" &&
|
|
257
|
+
pageFolder->slug.current == "blog" &&
|
|
258
|
+
defined(slug.current) &&
|
|
259
|
+
slug.current != "" &&
|
|
260
|
+
slug.current != "/" &&
|
|
261
|
+
(
|
|
262
|
+
!defined($category) ||
|
|
263
|
+
$category == "" ||
|
|
264
|
+
$category in pageBuilder[_ref in *[_type == "blogContent"]._id][0]->categories[]->slug.current
|
|
265
|
+
)
|
|
266
|
+
])
|
|
267
|
+
`)
|
|
268
|
+
|
|
269
|
+
export const ALL_BLOG_CATEGORIES_QUERY = defineQuery(`
|
|
270
|
+
*[_type == "blogCategory"] | order(title asc) {
|
|
271
|
+
_id,
|
|
272
|
+
title,
|
|
273
|
+
slug
|
|
274
|
+
}
|
|
275
|
+
`)
|
|
276
|
+
|
|
196
277
|
// Company Data
|
|
197
278
|
export const COMPANY_DATA_QUERY = defineQuery(`
|
|
198
279
|
*[_type == "companyData"][0]{
|
|
@@ -235,47 +316,79 @@ const navMegaMenuProjection = `
|
|
|
235
316
|
}
|
|
236
317
|
`
|
|
237
318
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
319
|
+
const navbarProjection = `
|
|
320
|
+
logo{
|
|
321
|
+
...,
|
|
322
|
+
asset->{
|
|
323
|
+
_id,
|
|
324
|
+
url,
|
|
325
|
+
metadata { dimensions }
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
navigationItems[]{
|
|
329
|
+
_key,
|
|
330
|
+
title,
|
|
331
|
+
itemType,
|
|
332
|
+
${navLinkProjection},
|
|
333
|
+
megaMenu{
|
|
334
|
+
${navMegaMenuProjection}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
ctaButtons[]{
|
|
338
|
+
_key,
|
|
339
|
+
label,
|
|
340
|
+
"link": link[0]{
|
|
341
|
+
${linkItemProjection}
|
|
256
342
|
},
|
|
257
|
-
|
|
343
|
+
variant
|
|
344
|
+
}
|
|
345
|
+
`
|
|
346
|
+
|
|
347
|
+
const footerProjection = `
|
|
348
|
+
links[]{
|
|
349
|
+
_key,
|
|
350
|
+
title,
|
|
351
|
+
items[]{
|
|
258
352
|
_key,
|
|
259
353
|
label,
|
|
260
|
-
|
|
261
|
-
${linkItemProjection}
|
|
262
|
-
},
|
|
263
|
-
variant
|
|
354
|
+
href
|
|
264
355
|
}
|
|
265
356
|
}
|
|
357
|
+
`
|
|
358
|
+
|
|
359
|
+
const companyDataProjection = `
|
|
360
|
+
socialLinks[]{
|
|
361
|
+
_key,
|
|
362
|
+
name,
|
|
363
|
+
icon,
|
|
364
|
+
url,
|
|
365
|
+
label
|
|
366
|
+
}
|
|
367
|
+
`
|
|
368
|
+
|
|
369
|
+
export const NAVBAR_QUERY = defineQuery(`
|
|
370
|
+
*[_type == "navbar"][0]{
|
|
371
|
+
${navbarProjection}
|
|
372
|
+
}
|
|
266
373
|
`)
|
|
267
374
|
|
|
268
375
|
// Footer
|
|
269
376
|
export const FOOTER_QUERY = defineQuery(`
|
|
270
377
|
*[_type == "footer"][0]{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
378
|
+
${footerProjection}
|
|
379
|
+
}
|
|
380
|
+
`)
|
|
381
|
+
|
|
382
|
+
export const SITE_LAYOUT_QUERY = defineQuery(`
|
|
383
|
+
{
|
|
384
|
+
"navbar": *[_type == "navbar"][0]{
|
|
385
|
+
${navbarProjection}
|
|
386
|
+
},
|
|
387
|
+
"footer": *[_type == "footer"][0]{
|
|
388
|
+
${footerProjection}
|
|
389
|
+
},
|
|
390
|
+
"companyData": *[_type == "companyData"][0]{
|
|
391
|
+
${companyDataProjection}
|
|
279
392
|
}
|
|
280
393
|
}
|
|
281
394
|
`)
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { table } from "@sanity/table"
|
|
2
2
|
import { defineConfig } from "sanity"
|
|
3
|
-
import {
|
|
4
|
-
defineDocuments,
|
|
5
|
-
defineLocations,
|
|
6
|
-
presentationTool,
|
|
7
|
-
} from "sanity/presentation"
|
|
8
3
|
import { structureTool } from "sanity/structure"
|
|
9
4
|
import { media } from "sanity-plugin-media"
|
|
10
5
|
import { createConfirmPublishAction } from "./confirm-publish-action"
|
|
11
|
-
import {
|
|
6
|
+
import { HOMEPAGE_DOCUMENT_ID } from "./constants"
|
|
7
|
+
import { dataset, projectId } from "./env"
|
|
8
|
+
import { presentation } from "./presentation"
|
|
12
9
|
import { schema } from "./schemas"
|
|
13
10
|
import { singletonComponentTypes } from "./singletons"
|
|
14
11
|
import { structure } from "./structure"
|
|
@@ -23,46 +20,7 @@ const singletonDocumentActions = new Set([
|
|
|
23
20
|
|
|
24
21
|
const isSingletonDocument = (schemaType: string, documentId?: string) =>
|
|
25
22
|
singletonComponentTypes.has(schemaType) ||
|
|
26
|
-
(schemaType === "page" && documentId ===
|
|
27
|
-
|
|
28
|
-
const MAX_FOLDER_DEPTH = 6
|
|
29
|
-
|
|
30
|
-
const buildNestedSlugExpression = (
|
|
31
|
-
parentReferenceField: string,
|
|
32
|
-
leafSlugField: string
|
|
33
|
-
) => {
|
|
34
|
-
const cases = Array.from({ length: MAX_FOLDER_DEPTH }, (_, index) => {
|
|
35
|
-
const depth = MAX_FOLDER_DEPTH - index
|
|
36
|
-
const parentSlugRefs = Array.from({ length: depth }, (_, parentIndex) => {
|
|
37
|
-
const remainingDepth = depth - parentIndex - 1
|
|
38
|
-
return `${parentReferenceField}${"->parentFolder".repeat(remainingDepth)}->slug.current`
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const pathDefinedChecks = parentSlugRefs
|
|
42
|
-
.map((field) => `defined(${field})`)
|
|
43
|
-
.join(" && ")
|
|
44
|
-
|
|
45
|
-
const childPath = [...parentSlugRefs, leafSlugField].join(' + "/" + ')
|
|
46
|
-
const folderRootPath = parentSlugRefs.join(' + "/" + ')
|
|
47
|
-
|
|
48
|
-
return [
|
|
49
|
-
`${pathDefinedChecks} && ${leafSlugField} == "/" => ${folderRootPath}`,
|
|
50
|
-
`${pathDefinedChecks} && defined(${leafSlugField}) => ${childPath}`,
|
|
51
|
-
]
|
|
52
|
-
}).flat()
|
|
53
|
-
|
|
54
|
-
return `
|
|
55
|
-
select(
|
|
56
|
-
${cases.join(",\n ")},
|
|
57
|
-
${leafSlugField}
|
|
58
|
-
)
|
|
59
|
-
`
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const pageResolvedSlugExpression = buildNestedSlugExpression(
|
|
63
|
-
"pageFolder",
|
|
64
|
-
"slug.current"
|
|
65
|
-
)
|
|
23
|
+
(schemaType === "page" && documentId === HOMEPAGE_DOCUMENT_ID)
|
|
66
24
|
|
|
67
25
|
export default defineConfig({
|
|
68
26
|
basePath: "/studio",
|
|
@@ -151,60 +109,7 @@ export default defineConfig({
|
|
|
151
109
|
},
|
|
152
110
|
plugins: [
|
|
153
111
|
structureTool({ structure }),
|
|
154
|
-
|
|
155
|
-
presentationTool({
|
|
156
|
-
name: "preview",
|
|
157
|
-
title: "Preview",
|
|
158
|
-
resolve: {
|
|
159
|
-
// Map routes to documents and GROQ filters
|
|
160
|
-
mainDocuments: defineDocuments([
|
|
161
|
-
{
|
|
162
|
-
route: "/",
|
|
163
|
-
filter: '_type == "page" && _id == "page-homepage"',
|
|
164
|
-
},
|
|
165
|
-
// Page builder pages - all other slugs (supports nested paths)
|
|
166
|
-
{
|
|
167
|
-
route: "/:slug+",
|
|
168
|
-
filter: `_type == "page" && ${pageResolvedSlugExpression} == $slug`,
|
|
169
|
-
},
|
|
170
|
-
]),
|
|
171
|
-
locations: {
|
|
172
|
-
page: defineLocations({
|
|
173
|
-
select: {
|
|
174
|
-
_id: "_id",
|
|
175
|
-
title: "title",
|
|
176
|
-
slug: "slug.current",
|
|
177
|
-
resolvedSlug: pageResolvedSlugExpression,
|
|
178
|
-
},
|
|
179
|
-
resolve: (doc) => {
|
|
180
|
-
if (doc?._id === "page-homepage") {
|
|
181
|
-
return {
|
|
182
|
-
locations: [{ title: doc?.title || "Homepage", href: "/" }],
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (doc?.resolvedSlug) {
|
|
186
|
-
return {
|
|
187
|
-
locations: [
|
|
188
|
-
{
|
|
189
|
-
title: doc?.title || "Page",
|
|
190
|
-
href: `/${doc.resolvedSlug}`,
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return { locations: [] }
|
|
196
|
-
},
|
|
197
|
-
}),
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
previewUrl: {
|
|
201
|
-
origin: previewURL,
|
|
202
|
-
draftMode: {
|
|
203
|
-
enable: "/api/draft-mode/enable",
|
|
204
|
-
disable: "/api/draft-mode/disable",
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
}),
|
|
112
|
+
presentation,
|
|
208
113
|
media(),
|
|
209
114
|
table(),
|
|
210
115
|
],
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import withBundleAnalyzer from "@next/bundle-analyzer"
|
|
2
2
|
import type { NextConfig } from "next"
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
|
|
4
6
|
const nextConfig: NextConfig = {
|
|
5
7
|
reactStrictMode: true,
|
|
6
8
|
reactCompiler: true,
|
|
@@ -62,6 +64,7 @@ const nextConfig: NextConfig = {
|
|
|
62
64
|
browserToTerminal: true,
|
|
63
65
|
},
|
|
64
66
|
experimental: {
|
|
67
|
+
prefetchInlining: true,
|
|
65
68
|
optimizePackageImports: [
|
|
66
69
|
"@react-three/drei",
|
|
67
70
|
"@react-three/fiber",
|
|
@@ -39,13 +39,11 @@
|
|
|
39
39
|
"react-use": "^17.6.0",
|
|
40
40
|
"sanity": "^5.17.1",
|
|
41
41
|
"sanity-plugin-media": "^4.1.1",
|
|
42
|
-
"schema-dts": "^2.0.0",
|
|
43
42
|
"tailwind-merge": "^3.5.0",
|
|
44
43
|
"zod": "^4.3.6"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
46
|
"@biomejs/biome": "2.4.8",
|
|
48
|
-
"@clack/prompts": "^1.1.0",
|
|
49
47
|
"@csstools/postcss-global-data": "^4.0.0",
|
|
50
48
|
"@next/bundle-analyzer": "16.2.1",
|
|
51
49
|
"@svgr/webpack": "^8.1.0",
|
|
@@ -59,6 +57,7 @@
|
|
|
59
57
|
"cross-env": "^10.1.0",
|
|
60
58
|
"postcss-functions": "^4.0.2",
|
|
61
59
|
"postcss-preset-env": "^11.2.0",
|
|
60
|
+
"schema-dts": "^2.0.0",
|
|
62
61
|
"tailwindcss": "^4.2.2",
|
|
63
62
|
"typescript": "^5.9.3"
|
|
64
63
|
},
|
package/src/templates/next-pagebuilder/components/page-builder/components/post-collection/index.tsx
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { sanityFetch } from "@/lib/integrations/sanity/live"
|
|
2
|
-
import { ALL_BLOG_ARTICLES_QUERY } from "@/lib/integrations/sanity/queries"
|
|
3
|
-
import { ContentGrid } from "./content-grid"
|
|
4
|
-
import type { ContentCollectionBlock } from "./types"
|
|
5
|
-
|
|
6
|
-
type ContentCollectionProps = {
|
|
7
|
-
block: ContentCollectionBlock
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export async function ContentCollection({ block }: ContentCollectionProps) {
|
|
11
|
-
const { data: articles } = await sanityFetch({
|
|
12
|
-
query: ALL_BLOG_ARTICLES_QUERY,
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
if (!articles?.length) return null
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<section className="flex flex-col gap-8 py-8">
|
|
20
|
-
{block.subtitle ? (
|
|
21
|
-
<h2 className="font-medium text-2xl leading-tight">
|
|
22
|
-
{block.subtitle}
|
|
23
|
-
</h2>
|
|
24
|
-
) : null}
|
|
25
|
-
<ContentGrid articles={articles} />
|
|
26
|
-
</section>
|
|
27
|
-
)
|
|
28
|
-
}
|