diff --git a/app/(site)/[locale]/[...slug]/page.tsx b/app/(site)/[locale]/[...slug]/page.tsx
index fa4626161..4b2d276f6 100644
--- a/app/(site)/[locale]/[...slug]/page.tsx
+++ b/app/(site)/[locale]/[...slug]/page.tsx
@@ -1,5 +1,7 @@
import CategoryPage from '@/components/pages/category-page';
import ProductPage from '@/components/pages/product-page';
+import SearchPage from '@/components/pages/search-page';
+import SearchPagePreview from '@/components/pages/search-page-preview';
import SinglePage from '@/components/pages/single-page';
import SinglePagePreview from '@/components/pages/single-page-preview';
import PreviewProvider from '@/components/preview-provider';
@@ -55,6 +57,8 @@ export default async function Page({ params }: PageParams) {
pageData = await getCachedClient()(query, queryParams);
} else if (docType === 'category') {
pageData = await getCachedClient()(query, queryParams);
+ } else if (docType === 'search') {
+ pageData = await getCachedClient()(query, queryParams);
} else {
return;
}
@@ -65,6 +69,7 @@ export default async function Page({ params }: PageParams) {
return (
{docType === 'page' && }
+ {docType === 'search' && }
);
}
@@ -74,6 +79,7 @@ export default async function Page({ params }: PageParams) {
{docType === 'page' && }
{docType === 'product' && }
{docType === 'category' && }
+ {docType === 'search' && }
>
);
}
diff --git a/app/api/preview/route.ts b/app/api/preview/route.ts
index 092ff8336..5f1dce999 100644
--- a/app/api/preview/route.ts
+++ b/app/api/preview/route.ts
@@ -22,9 +22,7 @@ export async function GET(request: Request) {
Location: `/${locale}`,
},
})
- }
-
- if (type === 'page') {
+ } else {
return new Response(null, {
status: 307,
headers: {
diff --git a/components/pages/search-page-preview.tsx b/components/pages/search-page-preview.tsx
new file mode 100644
index 000000000..ab080523d
--- /dev/null
+++ b/components/pages/search-page-preview.tsx
@@ -0,0 +1,26 @@
+'use client';
+
+import PreviewBanner from '@/components/ui/preview-banner';
+import { searchPageQuery } from '@/lib/sanity/queries';
+import { useLiveQuery } from '@sanity/preview-kit';
+import SearchPage from './search-page';
+
+interface SearchPagePreviewParams {
+ initialData: [];
+ params: {
+ locale: string;
+ slug: string;
+ };
+}
+
+export default function SearchPagePreview({ initialData, params }: SearchPagePreviewParams) {
+ const [data] = useLiveQuery(initialData, searchPageQuery, params);
+
+ return (
+ <>
+
+ {/* @ts-ignore */}
+
+ >
+ );
+}
diff --git a/app/(site)/[locale]/sok/page.tsx b/components/pages/search-page.tsx
similarity index 71%
rename from app/(site)/[locale]/sok/page.tsx
rename to components/pages/search-page.tsx
index 2e8e43f2c..868ffb416 100644
--- a/app/(site)/[locale]/sok/page.tsx
+++ b/components/pages/search-page.tsx
@@ -1,17 +1,16 @@
-'use client';
-
import Search from '@/components/search/search';
import SearchResult from '@/components/search/search-result';
import Text from '@/components/ui/text/text';
-import { useTranslations } from 'next-intl';
-export default function SearchPage() {
- const t = useTranslations('search');
+interface SearchPageParams {
+ data: object | any;
+}
+export default function SearchPage({ data }: SearchPageParams) {
return (
- {t('search')}
+ {data?.title}
diff --git a/helpers/get-query-from-slug.ts b/helpers/get-query-from-slug.ts
index 83657ca3f..3a9a64001 100644
--- a/helpers/get-query-from-slug.ts
+++ b/helpers/get-query-from-slug.ts
@@ -1,7 +1,8 @@
import {
categoryQuery,
pageQuery,
- productQuery
+ productQuery,
+ searchPageQuery
} from '@/lib/sanity/queries';
import { groq } from 'next-sanity';
@@ -10,6 +11,7 @@ const getQueryFromSlug = (slugArray: string[], locale: string) => {
'product': groq`${productQuery}`,
'category': groq`${categoryQuery}`,
'page': groq`${pageQuery}`,
+ 'search': groq`${searchPageQuery}`
}
let docType = ''
@@ -26,6 +28,8 @@ const getQueryFromSlug = (slugArray: string[], locale: string) => {
docType = `product`
} else if (slugStart === `kategori` || slugStart === `category`) {
docType = `category`
+ } else if (slugStart === `sok` || slugStart === `search`) {
+ docType = `search`
} else {
docType = `page`
}
diff --git a/lib/sanity/desk/index.ts b/lib/sanity/desk/index.ts
index 3bcb06d55..2128da084 100644
--- a/lib/sanity/desk/index.ts
+++ b/lib/sanity/desk/index.ts
@@ -1,16 +1,17 @@
/**
* Desk structure overrides
*/
-import {ListItemBuilder, StructureResolver} from 'sanity/desk'
+import { ListItemBuilder, StructureResolver } from 'sanity/desk'
+import blurbs from './blurb-structure'
import categories from './category-structure'
import home from './home-structure'
+import navigation from './navigation-structure'
import pages from './page-structure'
import products from './product-structure'
-import settings from './settings-structure'
-import blurbs from './blurb-structure'
+import search from './search-structure'
import sections from './section-structure'
+import settings from './settings-structure'
import usps from './usp-structure'
-import navigation from './navigation-structure'
/**
* Desk structure overrides
@@ -46,7 +47,8 @@ const hiddenDocTypes = (listItem: ListItemBuilder) => {
'usp',
'navigation',
'footerMenu',
- 'utilityMenu'
+ 'utilityMenu',
+ 'search'
].includes(id)
}
@@ -64,9 +66,9 @@ export const structure: StructureResolver = (S, context) =>
usps(S, context),
sections(S, context),
S.divider(),
- navigation(S, context),
- S.divider(),
settings(S, context),
+ search(S, context),
+ navigation(S, context),
S.divider(),
...S.documentTypeListItems().filter(hiddenDocTypes),
S.divider(),
diff --git a/lib/sanity/desk/search-structure.ts b/lib/sanity/desk/search-structure.ts
new file mode 100644
index 000000000..83c9c1415
--- /dev/null
+++ b/lib/sanity/desk/search-structure.ts
@@ -0,0 +1,34 @@
+import { EyeOpenIcon, MasterDetailIcon } from '@sanity/icons'
+import { SanityDocument } from 'sanity'
+import Iframe from 'sanity-plugin-iframe-pane'
+import { ListItemBuilder } from 'sanity/desk'
+import defineStructure from '../utils/define-structure'
+import getPreviewUrl from '../utils/get-preview-url'
+
+export default defineStructure((S) =>
+ S.listItem()
+ .title('Search pages')
+ .schemaType('search')
+ .child (
+ S.documentList()
+ .title('Search pages')
+ .filter('_type == "search"')
+ .child(id =>
+ S.document()
+ .schemaType("search")
+ .id(id)
+ .views([
+ S.view
+ .form()
+ .icon(MasterDetailIcon),
+ S.view
+ .component(Iframe)
+ .icon(EyeOpenIcon)
+ .options({
+ url: (doc: SanityDocument) => getPreviewUrl(doc),
+ })
+ .title('Preview')
+ ])
+ )
+ )
+)
diff --git a/lib/sanity/queries.tsx b/lib/sanity/queries.tsx
index 4e3e5bae3..fb8a0cd4c 100644
--- a/lib/sanity/queries.tsx
+++ b/lib/sanity/queries.tsx
@@ -178,6 +178,19 @@ export const homePageQuery = `*[_type == "home" && language == $locale][0] {
}
}`;
+export const searchPageQuery = `*[_type == "search" && language == $locale][0] {
+ _type,
+ title,
+ "locale": language,
+ "translations": *[_type == "translation.metadata" && references(^._id)].translations[].value->{
+ title,
+ "locale": language
+ },
+ seo {
+ ${seoFields}
+ }
+}`;
+
// Page query
export const pageQuery = `*[_type == "page" && slug.current == $slug && language == $locale][0] {
_type,
diff --git a/lib/sanity/schemas/documents/category.tsx b/lib/sanity/schemas/documents/category.tsx
index 493df701c..e7d6da08d 100644
--- a/lib/sanity/schemas/documents/category.tsx
+++ b/lib/sanity/schemas/documents/category.tsx
@@ -1,19 +1,19 @@
-import {TagIcon} from '@sanity/icons'
-import {defineField, defineType} from 'sanity'
-import {slugWithLocalizedType} from './slugWithLocalizedType'
-import {languages} from '../../languages'
-import {validateImage} from '../../utils/validation'
+import { TagIcon } from '@sanity/icons';
+import { defineField, defineType } from 'sanity';
+import { languages } from '../../languages';
+import { validateImage } from '../../utils/validation';
+import { slugWithLocalizedType } from '../slugWithLocalizedType';
const GROUPS = [
{
name: 'editorial',
- title: 'Editorial',
+ title: 'Editorial'
},
{
name: 'seo',
- title: 'SEO',
- },
-]
+ title: 'SEO'
+ }
+];
export default defineType({
name: 'category',
@@ -27,7 +27,7 @@ export default defineType({
name: 'language',
type: 'string',
readOnly: true,
- description: 'Language of this document.',
+ description: 'Language of this document.'
// hidden: true,
}),
// Title
@@ -35,7 +35,7 @@ export default defineType({
name: 'title',
title: 'Title',
type: 'string',
- description: 'Category title.',
+ description: 'Category title.'
}),
// Slug
slugWithLocalizedType('category', 'title'),
@@ -60,67 +60,67 @@ export default defineType({
name: 'image',
type: 'mainImage',
title: 'Image',
- validation: (Rule) => validateImage(Rule, true),
+ validation: (Rule) => validateImage(Rule, true)
}),
defineField({
name: 'description',
title: 'Description',
type: 'text',
rows: 5,
- description: 'Description of this category.',
+ description: 'Description of this category.'
}),
defineField({
name: 'id',
title: 'ID',
type: 'number',
- description: 'Unique ID.',
+ description: 'Unique ID.'
}),
defineField({
name: 'categoryId',
title: 'Category ID',
type: 'number',
- description: 'Unique category ID.',
+ description: 'Unique category ID.'
}),
defineField({
name: 'parentId',
title: 'Parent ID',
type: 'number',
- description: 'Unique parent category ID.',
+ description: 'Unique parent category ID.'
}),
// SEO
defineField({
name: 'seo',
title: 'SEO',
type: 'seo',
- group: 'seo',
- }),
+ group: 'seo'
+ })
],
orderings: [
{
name: 'titleAsc',
title: 'Title (A-Z)',
- by: [{field: 'title', direction: 'asc'}],
+ by: [{ field: 'title', direction: 'asc' }]
},
{
name: 'titleDesc',
title: 'Title (Z-A)',
- by: [{field: 'title', direction: 'desc'}],
- },
+ by: [{ field: 'title', direction: 'desc' }]
+ }
],
preview: {
select: {
title: 'title',
- language: 'language',
+ language: 'language'
},
prepare(selection) {
- const {title, language} = selection
- const currentLang = languages.find((lang) => lang.id === language)
+ const { title, language } = selection;
+ const currentLang = languages.find((lang) => lang.id === language);
return {
title,
subtitle: `${currentLang ? currentLang.title : ''}`,
- media: TagIcon,
- }
- },
- },
-})
+ media: TagIcon
+ };
+ }
+ }
+});
diff --git a/lib/sanity/schemas/documents/page.tsx b/lib/sanity/schemas/documents/page.tsx
index 7b040327b..6301f0fe6 100644
--- a/lib/sanity/schemas/documents/page.tsx
+++ b/lib/sanity/schemas/documents/page.tsx
@@ -1,8 +1,8 @@
-import {DocumentIcon} from '@sanity/icons'
-import {defineField} from 'sanity'
-import {languages} from '../../languages'
-import {COMPONENT_REFERENCES} from '../../constants'
-import {slugWithLocalizedType} from './slugWithLocalizedType'
+import { DocumentIcon } from '@sanity/icons';
+import { defineField } from 'sanity';
+import { COMPONENT_REFERENCES } from '../../constants';
+import { languages } from '../../languages';
+import { slugWithLocalizedType } from '../slugWithLocalizedType';
export default defineField({
name: 'page',
@@ -12,19 +12,19 @@ export default defineField({
groups: [
{
name: 'editorial',
- title: 'Editorial',
+ title: 'Editorial'
},
{
name: 'seo',
- title: 'SEO',
- },
+ title: 'SEO'
+ }
],
fields: [
defineField({
name: 'language',
type: 'string',
readOnly: true,
- description: 'Language of this document.',
+ description: 'Language of this document.'
// hidden: true,
}),
// Title
@@ -33,7 +33,7 @@ export default defineField({
title: 'Title',
type: 'string',
description: 'Page title.',
- validation: (Rule) => Rule.required(),
+ validation: (Rule) => Rule.required()
}),
// Slug
slugWithLocalizedType('page', 'title'),
@@ -44,32 +44,32 @@ export default defineField({
type: 'array',
group: 'editorial',
description: 'Add, reorder, edit or delete page sections.',
- of: COMPONENT_REFERENCES,
+ of: COMPONENT_REFERENCES
}),
// SEO
defineField({
name: 'seo',
title: 'SEO',
type: 'seo',
- group: 'seo',
- }),
+ group: 'seo'
+ })
],
preview: {
select: {
seoImage: 'seo.image',
title: 'title',
- language: 'language',
+ language: 'language'
},
prepare(selection) {
- const {seoImage, title, language} = selection
+ const { seoImage, title, language } = selection;
- const currentLang = languages.find((lang) => lang.id === language)
+ const currentLang = languages.find((lang) => lang.id === language);
return {
media: seoImage,
title,
- subtitle: `${currentLang ? currentLang.title : ''}`,
- }
- },
- },
-})
+ subtitle: `${currentLang ? currentLang.title : ''}`
+ };
+ }
+ }
+});
diff --git a/lib/sanity/schemas/documents/product.tsx b/lib/sanity/schemas/documents/product.tsx
index 8f3b94d33..3859a2bba 100644
--- a/lib/sanity/schemas/documents/product.tsx
+++ b/lib/sanity/schemas/documents/product.tsx
@@ -1,8 +1,8 @@
import { PackageIcon } from '@sanity/icons';
import { defineField, defineType } from 'sanity';
-import { slugWithLocalizedType } from './slugWithLocalizedType';
import { languages } from '../../languages';
import { validateImage } from '../../utils/validation';
+import { slugWithLocalizedType } from '../slugWithLocalizedType';
const GROUPS = [
{
diff --git a/lib/sanity/schemas/index.ts b/lib/sanity/schemas/index.ts
index ba83b7160..026ce0831 100644
--- a/lib/sanity/schemas/index.ts
+++ b/lib/sanity/schemas/index.ts
@@ -12,14 +12,14 @@
// ]
// Document types
+import blurb from './documents/blurb'
import category from './documents/category'
+import footerMenu from './documents/footerMenu'
import page from './documents/page'
import product from './documents/product'
import productVariant from './documents/productVariant'
-import blurb from './documents/blurb'
import section from './documents/section'
import usp from './documents/usp'
-import footerMenu from './documents/footerMenu'
const documents = [
category,
@@ -34,11 +34,11 @@ const documents = [
// Singleton document types
import home from './singletons/home'
+import search from './singletons/search'
import settings from './singletons/settings'
import utilityMenu from './singletons/utilityMenu'
-// import navigation from './singletons/navigation'
-const singletons = [home, settings, utilityMenu]
+const singletons = [home, settings, utilityMenu, search]
// Block content
import body from './blocks/body'
@@ -47,17 +47,17 @@ const blocks = [body]
// Object types
import banner from './objects/banner'
-import linkExternal from './objects/linkExternal'
-import linkInternal from './objects/linkInternal'
-import hero from './objects/hero'
-import seo from './objects/seo'
-import mainImage from './objects/mainImage'
-import slider from './objects/slider'
import blurbSection from './objects/blurbSection'
import filteredProductList from './objects/filteredProductList'
-import uspSection from './objects/uspSection'
-import reusableSection from './objects/reusableSection'
+import hero from './objects/hero'
+import linkExternal from './objects/linkExternal'
+import linkInternal from './objects/linkInternal'
+import mainImage from './objects/mainImage'
import menu from './objects/menu'
+import reusableSection from './objects/reusableSection'
+import seo from './objects/seo'
+import slider from './objects/slider'
+import uspSection from './objects/uspSection'
const objects = [
linkExternal,
diff --git a/lib/sanity/schemas/singletons/search.tsx b/lib/sanity/schemas/singletons/search.tsx
new file mode 100644
index 000000000..0d8bc25e2
--- /dev/null
+++ b/lib/sanity/schemas/singletons/search.tsx
@@ -0,0 +1,52 @@
+import { SearchIcon } from '@sanity/icons';
+import { defineField } from 'sanity';
+import { languages } from '../../languages';
+import { slugWithLocalizedType } from '../slugWithLocalizedType';
+
+export default defineField({
+ name: 'search',
+ title: 'Search',
+ type: 'document',
+ icon: SearchIcon,
+ fields: [
+ defineField({
+ name: 'language',
+ type: 'string',
+ readOnly: true,
+ description: 'Language of this document.'
+ // hidden: true,
+ }),
+ // Title
+ {
+ name: 'title',
+ title: 'Title',
+ type: 'string',
+ description: 'Page title.',
+ validation: (Rule) => Rule.required()
+ },
+ // Slug
+ slugWithLocalizedType('search', 'title'),
+ // SEO
+ defineField({
+ name: 'seo',
+ title: 'SEO',
+ type: 'seo'
+ })
+ ],
+ preview: {
+ select: {
+ title: 'title',
+ language: 'language'
+ },
+ prepare(selection) {
+ const { title, language } = selection;
+
+ const currentLang = languages.find((lang) => lang.id === language);
+
+ return {
+ title: `${title}`,
+ subtitle: `${currentLang ? currentLang.title : ''}`
+ };
+ }
+ }
+});
diff --git a/lib/sanity/schemas/documents/slugWithLocalizedType.ts b/lib/sanity/schemas/slugWithLocalizedType.ts
similarity index 91%
rename from lib/sanity/schemas/documents/slugWithLocalizedType.ts
rename to lib/sanity/schemas/slugWithLocalizedType.ts
index d2880d440..1b64aea34 100644
--- a/lib/sanity/schemas/documents/slugWithLocalizedType.ts
+++ b/lib/sanity/schemas/slugWithLocalizedType.ts
@@ -1,7 +1,7 @@
-import {Rule, Slug} from 'sanity'
+import { Rule, Slug } from 'sanity';
import slugify from "slugify";
-import { i18n } from "../../languages";
-import { localizedTypes } from "../../localizedTypes";
+import { i18n } from "../languages";
+import { localizedTypes } from "../localizedTypes";
const MAX_LENGTH = 96
diff --git a/sanity.config.ts b/sanity.config.ts
index 06a27533e..e38c99e73 100644
--- a/sanity.config.ts
+++ b/sanity.config.ts
@@ -13,7 +13,7 @@ const devOnlyPlugins = [visionTool()]
const singletonActions = new Set(["publish", "discardChanges", "restore"])
// Define the singleton document types
-const singletonTypes = new Set(["settings", "home", "utilityMenu", "media.tag"])
+const singletonTypes = new Set(["settings", "home", "utilityMenu", "media.tag", ])
// console.log(process.env.SANITY_API_READ_TOKEN)
@@ -45,7 +45,8 @@ export default defineConfig({
'section',
'usp',
'footerMenu',
- 'utilityMenu'
+ 'utilityMenu',
+ 'search'
],
// Optional
// languageField: `language`, // defauts to "language"