Skip to content

Commit

Permalink
Setup all sections and proper CMS default config
Browse files Browse the repository at this point in the history
  • Loading branch information
leomp12 committed Jan 3, 2025
1 parent 2d94f85 commit 89f6b60
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 70 deletions.
2 changes: 1 addition & 1 deletion functions/ssr/content/pages/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
{
"type": "product-shelf",
"collectionIdAndInfo": null,
"sort": "-price_discount",
"sort": "-price_discount,-sales",
"title": "",
"isHeadless": false,
"isShuffle": false,
Expand Down
81 changes: 75 additions & 6 deletions functions/ssr/src/pages/admin/config.json.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,83 @@
/* eslint-disable import/prefer-default-export */
import type { CmsConfigExtend } from '@@sf/content';
import { cmsFields as heroFields } from '~/sections/Hero.astro';
import { cmsFields as bannersGridFields } from '~/sections/BannersGrid.astro';
import { cmsFields as bannersGridFields } from '~/sections/BannersGridSection.astro';
import { cmsFields as pageTitleFields } from '~/sections/PageTitleSection.astro';
import { cmsFields as productShelfFields } from '~/sections/ProductShelfSection.astro';
import { cmsFields as searchShowcaseFields } from '~/sections/SearchShowcaseSection.astro';
import { cmsFields as contentEntryFields } from '~/sections/ContentEntrySection.astro';
import { cmsFields as customHtmlFields } from '~/sections/CustomHtmlSection.astro';
import { cmsFields as productDetailsFields } from '~/sections/ProductDetailsSection.astro';

export async function GET() {
return new Response(JSON.stringify({
fields: {
hero: heroFields,
const cmsConfig: CmsConfigExtend = {
components: {
hero: {
label: 'Hero slider',
fields: heroFields,
},
sections: {
'banners-grid': bannersGridFields,
'banners-grid': {
label: 'Grade de banners',
fields: bannersGridFields,
},
'page-title': {
label: 'Título da página (SEO)',
fields: pageTitleFields,
},
'product-shelf': {
label: 'Estante de produtos',
fields: productShelfFields,
},
'search-showcase': {
label: 'Vitrine de produtos e busca',
fields: searchShowcaseFields,
},
/*
'c:foo': {
label: 'Bar',
},
'c:foo-with-fields': {
label: 'Bar with fields',
fields: fooBarFields,
},
*/
'content-entry': {
label: 'Bloco de conteúdo',
fields: contentEntryFields,
},
'custom-html': {
label: 'HTML customizado',
fields: customHtmlFields,
},
breadcrumbs: {
label: 'Breadcrumbs',
},
'product-details': {
label: 'Detalhes do produto',
fields: productDetailsFields,
},
'related-products': {
label: 'Produtos relacionados',
},
'context-showcase': {
label: 'Vitrine da página',
fields: searchShowcaseFields,
},
'doc-banners': {
label: 'Banners da categoria/marca',
},
'doc-description': {
label: 'Descrição da categoria/marca',
},
},
},
}));
settingsMetafields: {
},
headerCustom: {
},
footerCustom: {
},
};
return new Response(JSON.stringify(cmsConfig));
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
---
import type { InferCmsOutput } from '@@sf/content';
import { bannerCmsFields } from '@@sf/composables/use-banner';
import type { CmsFields, InferCmsOutput } from '@@sf/content';
import { bannerListCmsField } from '@@sf/composables/use-banner';
import BannerPictures from '@@sf/components/BannerPictures.astro';
import Banner from '~/components/Banner.vue';
export const cmsFields = ({
title: {
widget: 'string',
label: { pt: 'Título', en: 'Title' },
},
titleLink: {
widget: 'string',
label: { pt: 'Link do título', en: 'Title link' },
},
banners: {
required: true,
widget: 'list',
fields: bannerCmsFields,
...bannerListCmsField,
},
}) as const;
}) as const satisfies CmsFields;
export type Props = InferCmsOutput<typeof cmsFields>
export type Props = InferCmsOutput<typeof cmsFields>;
const { banners = [] } = Astro.props;
---

Expand Down
25 changes: 25 additions & 0 deletions functions/ssr/src/sections/ContentEntrySection.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
import type { CmsFields, InferCmsOutput } from '@@sf/content';
import ContentEntry from '~/components/ContentEntry.vue';
export const cmsFields = ({
/* Keeping the fields optional because the data may come
from the current CMS collection entry. */
title: {
widget: 'text',
label: 'Título',
},
markdown: {
widget: 'markdown',
label: 'Conteúdo',
},
}) as const satisfies CmsFields;
export type Props = InferCmsOutput<typeof cmsFields>;
const {
title = '',
markdown = '',
} = Astro.props;
---

<ContentEntry {title} {markdown} />
16 changes: 16 additions & 0 deletions functions/ssr/src/sections/CustomHtmlSection.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
import type { CmsFields, InferCmsOutput } from '@@sf/content';
import ContentClearfix from '@@sf/components/ContentClearfix.vue';
export const cmsFields = ({
html: {
required: true,
widget: 'code',
label: 'HTML customizado',
},
}) as const satisfies CmsFields;
export type Props = InferCmsOutput<typeof cmsFields>;
---

<ContentClearfix html={Astro.props.html} />
18 changes: 3 additions & 15 deletions functions/ssr/src/sections/Hero.astro
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
---
import type { InferCmsOutput } from '@@sf/content';
import { bannerCmsFields } from '@@sf/composables/use-banner';
import { usePageHero } from '@@sf/layouts/use-page-main';
import { pageHeroCmsFields, usePageHero } from '@@sf/layouts/use-page-main';
import BannerPictures from '@@sf/components/BannerPictures.astro';
import HeroSlider from '~/components/HeroSlider.vue';
export const cmsFields = ({
autoplay: {
widget: 'number',
value_type: 'int',
label: 'Autoplay',
},
slides: {
required: true,
widget: 'list',
fields: bannerCmsFields,
},
}) as const;
export const cmsFields = pageHeroCmsFields;
type HeroContent = InferCmsOutput<typeof cmsFields>;
const { routeContext } = Astro.locals;
const heroSlider = (await usePageHero({ routeContext })).heroSlider as HeroContent;
const heroSlider = (await usePageHero({ routeContext })).heroSlider satisfies HeroContent;
const { slides = [], ...props } = heroSlider;
---

Expand Down
19 changes: 19 additions & 0 deletions functions/ssr/src/sections/PageTitleSection.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
import type { CmsFields, InferCmsOutput } from '@@sf/content';
import PageTitle from '~/components/PageTitle.vue';
export const cmsFields = ({
title: {
widget: 'string',
label: 'Título',
},
description: {
widget: 'text',
label: 'Descrição',
},
}) as const satisfies CmsFields;
export type Props = InferCmsOutput<typeof cmsFields>;
---

<PageTitle {...Astro.props} />
31 changes: 31 additions & 0 deletions functions/ssr/src/sections/ProductDetailsSection.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
import type { CmsFields, InferCmsOutput } from '@@sf/content';
import ProductDetails from '~/components/ProductDetails.vue';
import DocDescription from '~/components/DocDescription.vue';
import ProductSpecifications from '~/components/ProductSpecifications.vue';
export const cmsFields = ({
hasDescription: {
widget: 'boolean',
label: { pt: 'Mostrar descrição', en: 'Show description' },
},
hasSpecifications: {
widget: 'boolean',
label: { pt: 'Listar especificações', en: 'List specifications' },
},
}) as const satisfies CmsFields;
export type Props = InferCmsOutput<typeof cmsFields>;
const { hasDescription, hasSpecifications } = Astro.props;
const { routeContext: { apiContext } } = Astro.locals;
const product = apiContext.resource === 'products' && apiContext.doc;
---

{product && <>
<ProductDetails {product} client:sf="load">
<Fragment slot="description">
{hasDescription && <DocDescription apiDoc={product} />}
{hasSpecifications && <ProductSpecifications {product} />}
</Fragment>
</ProductDetails>
</>}
13 changes: 13 additions & 0 deletions functions/ssr/src/sections/ProductShelfSection.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
import type { InferCmsOutput } from '@@sf/content';
import { productShelfCmsFields } from '@@sf/composables/use-product-shelf';
import ProductShelf from '~/components/ProductShelf.vue';
export const cmsFields = productShelfCmsFields;
export type Props = InferCmsOutput<typeof cmsFields> & {
isRelatedProducts?: boolean;
};
---

<ProductShelf {...Astro.props} client:sf="lazy,interaction" />;
13 changes: 13 additions & 0 deletions functions/ssr/src/sections/SearchShowcaseSection.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
import type { InferCmsOutput } from '@@sf/content';
import { searchShowcaseCmsFields } from '@@sf/composables/use-search-showcase';
import SearchShowcase from '~/components/SearchShowcase.vue';
export const cmsFields = searchShowcaseCmsFields;
export type Props = InferCmsOutput<typeof cmsFields>;
---

<article class="min-h-[500px]">
<SearchShowcase {...Astro.props} client:sf="load" />
</article>
54 changes: 20 additions & 34 deletions functions/ssr/src/sections/_Sections.astro
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
---
import { usePageSections } from '@@sf/layouts/use-page-main';
import ContentClearfix from '@@sf/components/ContentClearfix.vue';
import BannersGrid from '~/sections/BannersGrid.astro';
import Breadcrumbs from '~/components/Breadcrumbs.vue';
import ProductShelf from '~/components/ProductShelf.vue';
import DocDescription from '~/components/DocDescription.vue';
import DocBanners from '~/components/DocBanners.vue';
import ProductDetails from '~/components/ProductDetails.vue';
import ProductSpecifications from '~/components/ProductSpecifications.vue';
import SearchShowcase from '~/components/SearchShowcase.vue';
import PageTitle from '~/components/PageTitle.vue';
import ContentEntry from '~/components/ContentEntry.vue';
import DocDescription from '~/components/DocDescription.vue';
import BannersGridSection from '~/sections/BannersGridSection.astro';
import ContentEntrySection from '~/sections/ContentEntrySection.astro';
import CustomHtmlSection from '~/sections/CustomHtmlSection.astro';
import PageTitleSection from '~/sections/PageTitleSection.astro';
import ProductShelfSection from '~/sections/ProductShelfSection.astro';
import ProductDetailsSection from '~/sections/ProductDetailsSection.astro';
import SearchShowcaseSection from '~/sections/SearchShowcaseSection.astro';
const { routeContext } = Astro.locals;
const { sections } = await usePageSections({
Expand All @@ -20,7 +19,7 @@ const { sections } = await usePageSections({
return { props: content };
},
});
const { cmsContent, apiContext } = routeContext;
const { cmsContent } = routeContext;
/* `apiContext` is surelly set here (from Main.astro)
cause route resource is required to define sections from content. */
---
Expand All @@ -34,42 +33,29 @@ cause route resource is required to define sections from content. */
};
}
switch (type) {
case 'banners-grid':
return <BannersGrid {...props} />;
case 'breadcrumbs':
return <Breadcrumbs />;
case 'content-entry':
return <ContentEntry {...props} />;
case 'custom-html':
return <ContentClearfix html={props.html} />;
case 'doc-banners':
return <DocBanners />;
case 'doc-description':
return <DocDescription />;
case 'banners-grid':
return <BannersGridSection {...props} />;
case 'content-entry':
return <ContentEntrySection {...props} />;
case 'custom-html':
return <CustomHtmlSection {...props} />;
case 'page-title':
return <PageTitle {...props} />;
return <PageTitleSection {...props} />;
case 'product-shelf':
case 'related-products':
props.isRelatedProducts = type === 'related-products';
return <ProductShelf {...props} client:sf="lazy,interaction" />;
case 'context-showcase':
return <ProductShelfSection {...props} />;
case 'search-showcase':
return <>
<article class="min-h-[500px]">
<SearchShowcase {...props} client:sf="load" />
</article>
</>;
case 'context-showcase':
return <SearchShowcaseSection {...props} />;
case 'product-details':
const { hasDescription, hasSpecifications } = props;
const product = apiContext.resource === 'products' && apiContext.doc;
return product && <>
<ProductDetails {product} client:sf="load">
<Fragment slot="description">
{hasDescription && <DocDescription apiDoc={product} />}
{hasSpecifications && <ProductSpecifications {product} />}
</Fragment>
</ProductDetails>
</>;
return <ProductDetailsSection {...props} />;
case 'c:foo':
return <div data-foo={props.foo}></div>;
default:
Expand Down

0 comments on commit 89f6b60

Please sign in to comment.