mirror of
https://github.com/vercel/commerce.git
synced 2025-05-19 16:07:01 +00:00
Test
This commit is contained in:
parent
1baa3c1f8d
commit
e49b0a06ae
@ -1,17 +1,14 @@
|
||||
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';
|
||||
// import PreviewProvider from '@/components/preview-provider';
|
||||
import getQueryFromSlug from '@/helpers/get-query-from-slug';
|
||||
import { getCachedClient } from 'lib/sanity/sanity.client';
|
||||
import { getCategory, getPage, getProduct, getSearch } from '@/lib/sanity/sanity.fetch';
|
||||
import type { Metadata } from 'next';
|
||||
import { draftMode } from 'next/headers';
|
||||
import { notFound } from 'next/navigation';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const runtime = 'edge';
|
||||
|
||||
export async function generateMetadata({
|
||||
params
|
||||
@ -20,18 +17,23 @@ export async function generateMetadata({
|
||||
}): Promise<Metadata> {
|
||||
const { slug, locale } = params;
|
||||
|
||||
const { query = '', queryParams } = getQueryFromSlug(slug, locale);
|
||||
const { queryParams, docType } = getQueryFromSlug(slug, locale);
|
||||
|
||||
const page = await getCachedClient()(query, queryParams);
|
||||
let page;
|
||||
|
||||
docType === 'page' && (page = await getPage(queryParams.slug, queryParams.locale));
|
||||
docType === 'product' && (page = await getProduct(queryParams.slug, queryParams.locale));
|
||||
docType === 'category' && (page = await getCategory(queryParams.slug, queryParams.locale));
|
||||
docType === 'search' && (page = await getSearch(queryParams.slug, queryParams.locale));
|
||||
|
||||
if (!page) return notFound();
|
||||
|
||||
return {
|
||||
title: `${page.seo?.title || page.title}`,
|
||||
description: page.seo?.description || page.bodySummary,
|
||||
description: page.seo?.description,
|
||||
openGraph: {
|
||||
publishedTime: page.createdAt,
|
||||
modifiedTime: page.updatedAt,
|
||||
// publishedTime: page.createdAt,
|
||||
// modifiedTime: page.updatedAt,
|
||||
type: 'article'
|
||||
}
|
||||
};
|
||||
@ -39,49 +41,38 @@ export async function generateMetadata({
|
||||
|
||||
interface PageParams {
|
||||
params: {
|
||||
locale: string;
|
||||
slug: string[];
|
||||
locale: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Page({ params }: PageParams) {
|
||||
const preview = draftMode().isEnabled ? { token: process.env.SANITY_API_READ_TOKEN } : undefined;
|
||||
|
||||
const { slug, locale } = params;
|
||||
|
||||
const { query = '', queryParams, docType } = getQueryFromSlug(slug, locale);
|
||||
const { queryParams, docType } = getQueryFromSlug(slug, locale);
|
||||
|
||||
let pageData;
|
||||
let data;
|
||||
|
||||
if (docType === 'page') {
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
data = await getPage(queryParams.slug, queryParams.locale);
|
||||
} else if (docType === 'product') {
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
data = await getProduct(queryParams.slug, queryParams.locale);
|
||||
} else if (docType === 'category') {
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
data = await getCategory(queryParams.slug, queryParams.locale);
|
||||
} else if (docType === 'search') {
|
||||
pageData = await getCachedClient()(query, queryParams);
|
||||
} else {
|
||||
return;
|
||||
data = await getSearch(queryParams.slug, queryParams.locale);
|
||||
}
|
||||
|
||||
if (!pageData) return notFound();
|
||||
|
||||
if (preview && preview.token) {
|
||||
return (
|
||||
<PreviewProvider token={preview.token}>
|
||||
{docType === 'page' && <SinglePagePreview initialData={pageData} params={queryParams} />}
|
||||
{docType === 'search' && <SearchPagePreview initialData={pageData} params={queryParams} />}
|
||||
</PreviewProvider>
|
||||
);
|
||||
if (!data) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{docType === 'page' && <SinglePage data={pageData} />}
|
||||
{docType === 'product' && <ProductPage data={pageData} />}
|
||||
{docType === 'category' && <CategoryPage data={pageData} />}
|
||||
{docType === 'search' && <SearchPage data={pageData} />}
|
||||
{docType === 'page' && <SinglePage data={data} />}
|
||||
{docType === 'product' && <ProductPage data={data} />}
|
||||
{docType === 'category' && <CategoryPage data={data} />}
|
||||
{docType === 'search' && <SearchPage data={data} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
import PreviewProvider from '@/components/preview/preview-provider';
|
||||
import { token } from '@/lib/sanity/sanity.fetch';
|
||||
import { Analytics } from '@vercel/analytics/react';
|
||||
import Footer from 'components/layout/footer/footer';
|
||||
import Header from 'components/layout/header/header';
|
||||
import { NextIntlClientProvider } from 'next-intl';
|
||||
import { Inter } from 'next/font/google';
|
||||
import { draftMode } from 'next/headers';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { ReactNode, Suspense } from 'react';
|
||||
import { supportedLanguages } from '../../../i18n-config';
|
||||
@ -54,7 +57,9 @@ export default async function LocaleLayout({ children, params: { locale } }: Loc
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
const isDraftMode = draftMode().isEnabled;
|
||||
|
||||
const layout = (
|
||||
<html lang={locale} className={inter.variable}>
|
||||
<body className="flex min-h-screen flex-col">
|
||||
<NextIntlClientProvider locale={locale} messages={messages}>
|
||||
@ -70,4 +75,10 @@ export default async function LocaleLayout({ children, params: { locale } }: Loc
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
if (isDraftMode) {
|
||||
return <PreviewProvider token={token!}>{layout}</PreviewProvider>;
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import { draftMode } from 'next/headers';
|
||||
import { notFound } from 'next/navigation';
|
||||
|
||||
export const runtime = 'edge';
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function generateMetadata({
|
||||
params
|
||||
@ -31,16 +30,12 @@ interface HomePageParams {
|
||||
}
|
||||
|
||||
export default async function IndexPage({ params }: HomePageParams) {
|
||||
// const preview = draftMode().isEnabled ? { token: process.env.SANITY_API_READ_TOKEN } : undefined;
|
||||
|
||||
const data = await getHomePage(params.locale);
|
||||
|
||||
if (!data && !draftMode().isEnabled) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
console.log('Preview:', draftMode().isEnabled);
|
||||
|
||||
return (
|
||||
<LiveQuery
|
||||
enabled={draftMode().isEnabled}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { previewSecretId } from '@/lib/sanity/sanity.api'
|
||||
import { client } from '@/lib/sanity/sanity.client'
|
||||
// import { previewSecretId } from '@/lib/sanity/sanity.api'
|
||||
// import { client } from '@/lib/sanity/sanity.client'
|
||||
import { token } from '@/lib/sanity/sanity.fetch'
|
||||
import { draftMode } from 'next/headers'
|
||||
import { isValidSecret } from 'sanity-plugin-iframe-pane/is-valid-secret'
|
||||
|
||||
export const runtime = 'edge'
|
||||
|
||||
@ -18,24 +17,27 @@ export async function GET(request: Request) {
|
||||
'The `SANITY_API_READ_TOKEN` environment variable is required.',
|
||||
)
|
||||
}
|
||||
|
||||
if (!secret) {
|
||||
return new Response('Invalid secret', { status: 401 })
|
||||
}
|
||||
|
||||
const authenticatedClient = client.withConfig({ token })
|
||||
// const authenticatedClient = client.withConfig({ token })
|
||||
|
||||
const validSecret = await isValidSecret(
|
||||
authenticatedClient,
|
||||
previewSecretId,
|
||||
secret,
|
||||
)
|
||||
// const validSecret = await isValidSecret(
|
||||
// authenticatedClient,
|
||||
// previewSecretId,
|
||||
// secret,
|
||||
// )
|
||||
|
||||
if (!validSecret) {
|
||||
return new Response('Invalid secret', { status: 401 })
|
||||
}
|
||||
// if (!validSecret) {
|
||||
// return new Response('Invalid secret', { status: 401 })
|
||||
// }
|
||||
|
||||
draftMode().enable()
|
||||
|
||||
console.log(draftMode())
|
||||
|
||||
if (type === 'home') {
|
||||
return new Response(null, {
|
||||
status: 307,
|
||||
|
@ -1,24 +1,22 @@
|
||||
'use client';
|
||||
|
||||
import { homePageQuery } from '@/lib/sanity/queries';
|
||||
import { useLiveQuery } from '@sanity/preview-kit';
|
||||
import dynamic from 'next/dynamic';
|
||||
import PreviewBanner from '../ui/preview-banner';
|
||||
import HomePage from './home-page';
|
||||
import type { IndexPageParams } from './home-page';
|
||||
|
||||
interface HomePagePreviewParams {
|
||||
initialData: [];
|
||||
params: {
|
||||
locale: string;
|
||||
};
|
||||
}
|
||||
const HomePage = dynamic(() => import('./home-page'));
|
||||
|
||||
export default function HomePagePreview({ initialData, params }: HomePagePreviewParams) {
|
||||
const [data] = useLiveQuery(initialData, homePageQuery, params);
|
||||
export default function HomePagePreview({ data }: IndexPageParams) {
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="text-center">Please start editing your Home document to see the preview!</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<HomePage data={data} />;{/* @ts-ignore */}
|
||||
<PreviewBanner title={data?.title} type={data?._type} />
|
||||
<HomePage data={data} />
|
||||
<PreviewBanner title={data?.title ? data.title : ''} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
import DynamicContentManager from '@/components/layout/dynamic-content-manager/dynamic-content-manager';
|
||||
import type { HomePagePayload } from '@/lib/sanity/sanity.types';
|
||||
interface IndexPageParams {
|
||||
|
||||
export type IndexPageParams = {
|
||||
data: HomePagePayload | null;
|
||||
}
|
||||
};
|
||||
|
||||
export default function HomePage({ data }: IndexPageParams) {
|
||||
// console.log(data);
|
||||
|
||||
return (
|
||||
<>
|
||||
<DynamicContentManager content={data?.content} />;
|
||||
|
30
components/preview/preview-provider.tsx
Normal file
30
components/preview/preview-provider.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
'use client';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
import { suspend } from 'suspend-react';
|
||||
|
||||
const LiveQueryProvider = dynamic(() => import('next-sanity/preview'));
|
||||
|
||||
// suspend-react cache is global, so we use a unique key to avoid collisions
|
||||
const UniqueKey = Symbol('lib/sanity.client');
|
||||
|
||||
export default function PreviewProvider({
|
||||
children,
|
||||
token
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
token: string;
|
||||
}) {
|
||||
const { client } = suspend(() => import('@/lib/sanity/sanity.client'), [UniqueKey]);
|
||||
if (!token) throw new TypeError('Missing token');
|
||||
return (
|
||||
<LiveQueryProvider
|
||||
client={client}
|
||||
token={token}
|
||||
// Uncomment below to see debug reports
|
||||
logger={console}
|
||||
>
|
||||
{children}
|
||||
</LiveQueryProvider>
|
||||
);
|
||||
}
|
@ -4,7 +4,7 @@ import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface PreviewBannerProps {
|
||||
title: string;
|
||||
title?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,9 @@ import { draftMode } from 'next/headers'
|
||||
|
||||
import { revalidateSecret } from './sanity.api'
|
||||
|
||||
import { homePageQuery } from './queries'
|
||||
import { categoryQuery, homePageQuery, pageQuery, productQuery, searchPageQuery } from './queries'
|
||||
|
||||
import { HomePagePayload } from './sanity.types'
|
||||
import { CategoryPayload, HomePagePayload, PagePayload, ProductPayload, SearchPayload } from './sanity.types'
|
||||
|
||||
export const token = process.env.SANITY_API_READ_TOKEN
|
||||
|
||||
@ -56,6 +56,38 @@ export function getHomePage(locale: string) {
|
||||
return sanityFetch<HomePagePayload | null>({
|
||||
query: homePageQuery,
|
||||
params: { locale },
|
||||
tags: ['home', 'products', 'categories'],
|
||||
tags: ['home', 'products', 'categories', 'page'],
|
||||
})
|
||||
}
|
||||
|
||||
export function getPage(slug: string, locale: string) {
|
||||
return sanityFetch<PagePayload | null>({
|
||||
query: pageQuery,
|
||||
params: { slug, locale },
|
||||
tags: ['page'],
|
||||
})
|
||||
}
|
||||
|
||||
export function getProduct(slug: string, locale: string) {
|
||||
return sanityFetch<ProductPayload | null>({
|
||||
query: productQuery,
|
||||
params: { slug, locale },
|
||||
tags: ['product'],
|
||||
})
|
||||
}
|
||||
|
||||
export function getCategory(slug: string, locale: string) {
|
||||
return sanityFetch<CategoryPayload | null>({
|
||||
query: categoryQuery,
|
||||
params: { slug, locale },
|
||||
tags: ['category'],
|
||||
})
|
||||
}
|
||||
|
||||
export function getSearch(slug: string, locale: string) {
|
||||
return sanityFetch<SearchPayload | null>({
|
||||
query: searchPageQuery,
|
||||
params: { slug, locale },
|
||||
tags: ['search'],
|
||||
})
|
||||
}
|
@ -10,3 +10,52 @@ export interface HomePagePayload {
|
||||
image: Image
|
||||
}
|
||||
}
|
||||
|
||||
export interface PagePayload {
|
||||
content?: []
|
||||
title?: string
|
||||
_type?: string
|
||||
slug?: string
|
||||
seo?: {
|
||||
title?: string;
|
||||
description?: string;
|
||||
image: Image
|
||||
}
|
||||
}
|
||||
|
||||
export interface ProductPayload {
|
||||
title?: string
|
||||
name?: string
|
||||
description?: string
|
||||
images?: Image[]
|
||||
currencyCode?: string
|
||||
_type?: string
|
||||
slug?: string
|
||||
seo?: {
|
||||
title?: string;
|
||||
description?: string;
|
||||
image: Image
|
||||
}
|
||||
}
|
||||
|
||||
export interface CategoryPayload {
|
||||
title?: string
|
||||
_type?: string
|
||||
slug?: string
|
||||
seo?: {
|
||||
title?: string;
|
||||
description?: string;
|
||||
image: Image
|
||||
}
|
||||
}
|
||||
|
||||
export interface SearchPayload {
|
||||
title?: string
|
||||
_type?: string
|
||||
slug?: string
|
||||
seo?: {
|
||||
title?: string;
|
||||
description?: string;
|
||||
image: Image
|
||||
}
|
||||
}
|
@ -57,6 +57,7 @@
|
||||
"slug": "^8.2.2",
|
||||
"slugify": "^1.6.5",
|
||||
"styled-components": "^5.3.10",
|
||||
"suspend-react": "^0.1.3",
|
||||
"tailwind-merge": "^1.12.0",
|
||||
"tailwindcss-animate": "^1.0.5"
|
||||
},
|
||||
|
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@ -119,6 +119,9 @@ dependencies:
|
||||
styled-components:
|
||||
specifier: ^5.3.10
|
||||
version: 5.3.11(@babel/core@7.22.10)(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)
|
||||
suspend-react:
|
||||
specifier: ^0.1.3
|
||||
version: 0.1.3(react@18.2.0)
|
||||
tailwind-merge:
|
||||
specifier: ^1.12.0
|
||||
version: 1.14.0
|
||||
@ -8169,6 +8172,14 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/suspend-react@0.1.3(react@18.2.0):
|
||||
resolution: {integrity: sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==}
|
||||
peerDependencies:
|
||||
react: '>=17.0'
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/symbol-tree@3.2.4:
|
||||
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
||||
dev: false
|
||||
|
Loading…
x
Reference in New Issue
Block a user