From 29d640f93b00fb4621824a8b08c0af3d7e9a3267 Mon Sep 17 00:00:00 2001 From: maksim hodasevich <47758224+dogfrogfog@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:01:24 +0100 Subject: [PATCH] feat: components with global data (#69) * fix: header footer slugs, moved to components folder * feat: add ability to create global components and edit them from a single place * feat: remove utility to resolve header and footer relations, move resolving relations to the component level, reusing useGlobalComponent hook * feat: rename globalComponent to globalData, update stories, schemas, types * feat: add globalData to hero for sanity component, change hero query to resolve globalData, add comment to use CSS variables as section background --- .../src/components/SectionContainer/index.tsx | 4 +- .../sanity/src/contentSections/Hero/index.tsx | 22 +- apps/sanity/src/contentSections/Hero/query.ts | 6 + .../sanity/src/contentSections/Hero/schema.ts | 9 +- .../src/generated/extracted-schema.json | 461 ++++++++++-------- apps/sanity/src/generated/extracted-types.ts | 81 ++- apps/storyblok/src/app/[[...slug]]/page.tsx | 3 - .../src/components/CoreLayout/index.tsx | 8 +- .../src/components/DataContext/index.tsx | 6 +- .../src/components/DataContext/types.ts | 2 +- apps/storyblok/src/components/Page/index.tsx | 17 +- apps/storyblok/src/components/Page/utils.ts | 27 - .../src/contentSections/Hero/index.tsx | 24 +- .../src/generated/components.production.json | 64 ++- .../dump/backup/stories/560303235.json | 31 +- .../dump/backup/stories/560303238.json | 14 +- .../dump/backup/stories/560303250.json | 14 +- .../dump/backup/stories/560836300.json | 31 +- .../dump/backup/stories/560836303.json | 20 +- .../dump/backup/stories/560838689.json | 20 +- .../dump/backup/stories/571196664.json | 12 +- .../dump/backup/stories/575494741.json | 48 +- .../dump/backup/stories/596037362.json | 58 +++ .../dump/backup/stories/596040297.json | 73 +++ .../dump/backup/stories/596040303.json | 186 +++++++ .../dump/backup/stories/596040305.json | 137 ++++++ .../src/generated/extracted-types.ts | 1 + apps/storyblok/src/lib/api.ts | 19 +- .../src/lib/hooks/useGlobalComponentData.tsx | 19 + .../ui/components/sections/hero/index.tsx | 2 +- 30 files changed, 996 insertions(+), 423 deletions(-) delete mode 100644 apps/storyblok/src/components/Page/utils.ts create mode 100644 apps/storyblok/src/generated/dump/backup/stories/596037362.json create mode 100644 apps/storyblok/src/generated/dump/backup/stories/596040297.json create mode 100644 apps/storyblok/src/generated/dump/backup/stories/596040303.json create mode 100644 apps/storyblok/src/generated/dump/backup/stories/596040305.json create mode 100644 apps/storyblok/src/lib/hooks/useGlobalComponentData.tsx diff --git a/apps/sanity/src/components/SectionContainer/index.tsx b/apps/sanity/src/components/SectionContainer/index.tsx index db6f48b..771eb35 100644 --- a/apps/sanity/src/components/SectionContainer/index.tsx +++ b/apps/sanity/src/components/SectionContainer/index.tsx @@ -36,7 +36,7 @@ export default function SectionContainer({ const cleanMarginTop = stegaClean(marginTop); const cleanMarginBottom = stegaClean(marginBottom); - const cleanBackgroundColor = stegaClean(backgroundColor); + const cleanBackgroundColor = stegaClean(backgroundColor); // implement using CSS variables const cleanMaxWidth = stegaClean(maxWidth); return ( @@ -45,7 +45,7 @@ export default function SectionContainer({ className={cn( "bg-bgColor overflow-x-hidden", className, - cleanBackgroundColor, + cleanBackgroundColor, // implement using CSS variables { "mt-0": cleanMarginTop === "none", "mb-0": cleanMarginBottom === "none", diff --git a/apps/sanity/src/contentSections/Hero/index.tsx b/apps/sanity/src/contentSections/Hero/index.tsx index 9b2c1e4..6c2be6c 100644 --- a/apps/sanity/src/contentSections/Hero/index.tsx +++ b/apps/sanity/src/contentSections/Hero/index.tsx @@ -12,11 +12,31 @@ import type { IHeroSectionProps } from "./types"; export default function HeroSection({ data }: IHeroSectionProps) { if (!data) return null; - const { title, text, image, links } = data; + const { title, text, image, links, globalData } = data; if (!title && !text?.text && !image?.image && (!links || links.length === 0)) return ; + if (globalData) { + const { + title: globalTitle, + text: globalText, + image: globalImage, + links: globalLinks, + } = globalData as any; + + return ( + + + + ); + } + return ( { + ..., + links[] { + ${LINK_FRAGMENT} + }, + }, links[] { ${LINK_FRAGMENT} } diff --git a/apps/sanity/src/contentSections/Hero/schema.ts b/apps/sanity/src/contentSections/Hero/schema.ts index 6c87d5d..da604de 100644 --- a/apps/sanity/src/contentSections/Hero/schema.ts +++ b/apps/sanity/src/contentSections/Hero/schema.ts @@ -13,9 +13,16 @@ export default { options: {}, name: "section.hero", title: "Hero", - type: "object", + type: "document", groups: commonGroups, fields: [ + defineField({ + name: "globalData", + title: "Global Data", + type: "reference", + to: [{ type: "section.hero" }], + group: CommonGroup.Content, + }), defineField({ name: "title", type: "string", diff --git a/apps/sanity/src/generated/extracted-schema.json b/apps/sanity/src/generated/extracted-schema.json index c7564b2..82f7abe 100644 --- a/apps/sanity/src/generated/extracted-schema.json +++ b/apps/sanity/src/generated/extracted-schema.json @@ -947,216 +947,267 @@ }, { "name": "section.hero", - "type": "type", - "value": { - "type": "object", - "attributes": { - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "section.hero" - } - }, - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": false - }, - "text": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "customRichText" - }, - "optional": true - }, - "image": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "customImage" - }, - "optional": true - }, - "links": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "customLink" + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "section.hero" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "globalData": { + "type": "objectAttribute", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" } - } - }, - "optional": false - }, - "marginTop": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "none" - }, - { - "type": "string", - "value": "base" - }, - { + }, + "_type": { + "type": "objectAttribute", + "value": { "type": "string", - "value": "lg" + "value": "reference" } - ] - }, - "optional": false - }, - "marginBottom": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "none" - }, - { - "type": "string", - "value": "base" + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" }, - { - "type": "string", - "value": "lg" - } - ] + "optional": true + } }, - "optional": false + "dereferencesTo": "section.hero" }, - "maxWidth": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "none" - }, - { - "type": "string", - "value": "base" - }, - { - "type": "string", - "value": "small" - } - ] - }, - "optional": false + "optional": true + }, + "title": { + "type": "objectAttribute", + "value": { + "type": "string" }, - "backgroundColor": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "light" - }, - { - "type": "string", - "value": "light-gray" - }, - { - "type": "string", - "value": "dark-gray" - }, - { - "type": "string", - "value": "dark" - }, - { - "type": "string", - "value": "none" - } - ] - }, - "optional": false + "optional": false + }, + "text": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "customRichText" }, - "backgroundImage": { - "type": "objectAttribute", - "value": { + "optional": true + }, + "image": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "customImage" + }, + "optional": true + }, + "links": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { "type": "object", "attributes": { - "asset": { + "_key": { "type": "objectAttribute", "value": { - "type": "object", - "attributes": { - "_ref": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "reference" - } - }, - "_weak": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "customLink" + } + } + }, + "optional": false + }, + "marginTop": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "none" + }, + { + "type": "string", + "value": "base" + }, + { + "type": "string", + "value": "lg" + } + ] + }, + "optional": false + }, + "marginBottom": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "none" + }, + { + "type": "string", + "value": "base" + }, + { + "type": "string", + "value": "lg" + } + ] + }, + "optional": false + }, + "maxWidth": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "none" + }, + { + "type": "string", + "value": "base" + }, + { + "type": "string", + "value": "small" + } + ] + }, + "optional": false + }, + "backgroundColor": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "light" + }, + { + "type": "string", + "value": "light-gray" + }, + { + "type": "string", + "value": "dark-gray" + }, + { + "type": "string", + "value": "dark" + }, + { + "type": "string", + "value": "none" + } + ] + }, + "optional": false + }, + "backgroundImage": { + "type": "objectAttribute", + "value": { + "type": "object", + "attributes": { + "asset": { + "type": "objectAttribute", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" } }, - "dereferencesTo": "sanity.imageAsset" + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } }, - "optional": true + "dereferencesTo": "sanity.imageAsset" }, - "hotspot": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageHotspot" - }, - "optional": true + "optional": true + }, + "hotspot": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageHotspot" }, - "crop": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageCrop" - }, - "optional": true + "optional": true + }, + "crop": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageCrop" }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "image" - } + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "image" } } - }, - "optional": true - } + } + }, + "optional": true } } }, @@ -3176,7 +3227,7 @@ }, { "type": "string", - "value": "ghostDark" + "value": "ghost-dark" } ] }, @@ -3403,16 +3454,38 @@ { "type": "object", "attributes": { - "_key": { + "_ref": { "type": "objectAttribute", "value": { "type": "string" } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true } }, + "dereferencesTo": "section.hero", "rest": { - "type": "inline", - "name": "section.hero" + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } } }, { diff --git a/apps/sanity/src/generated/extracted-types.ts b/apps/sanity/src/generated/extracted-types.ts index de22c02..cbeef8c 100644 --- a/apps/sanity/src/generated/extracted-types.ts +++ b/apps/sanity/src/generated/extracted-types.ts @@ -144,7 +144,17 @@ export type SectionPricingTable = { }; export type SectionHero = { + _id: string; _type: "section.hero"; + _createdAt: string; + _updatedAt: string; + _rev: string; + globalData?: { + _ref: string; + _type: "reference"; + _weak?: boolean; + [internalGroqTypeReferenceTo]?: "section.hero"; + }; title: string; text?: CustomRichText; image?: CustomImage; @@ -443,7 +453,7 @@ export type CustomLink = { | "secondary" | "badge" | "ghost" - | "ghostDark"; + | "ghost-dark"; size: "base" | "sm" | "lg"; }; @@ -481,9 +491,13 @@ export type Page = { | ({ _key: string; } & SectionCarousel) - | ({ + | { + _ref: string; + _type: "reference"; + _weak?: boolean; _key: string; - } & SectionHero) + [internalGroqTypeReferenceTo]?: "section.hero"; + } | ({ _key: string; } & SectionPricingTable) @@ -753,7 +767,7 @@ export type AllSanitySchemaTypes = export declare const internalGroqTypeReferenceTo: unique symbol; // Source: ./src/lib/api/queries.ts // Variable: PAGE_BY_SLUG_QUERY -// Query: *[_type == "page" && pathname.current == $slug][0] { _id, header->{ ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, sectionsBody[] { ..., _type == "section.hero" => { ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, _type == "section.linksList" => { ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, _type == "section.cardsGrid" => { ..., items[] { ..., link { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } } }, _type == "section.logos" => { ..., items[] { ..., link { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } } }, _type == "section.blog" => { ..., posts[] { ..., link { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } } }, }, footer->{ ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, title, "slug": pathname.current, seoTitle, seoDescription, ogImage, robots, theme, } +// Query: *[_type == "page" && pathname.current == $slug][0] { _id, header->{ ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, sectionsBody[] { ..., _type == "section.hero" => { ..., globalData->{ ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} }, }, links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, _type == "section.linksList" => { ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, _type == "section.cardsGrid" => { ..., items[] { ..., link { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } } }, _type == "section.logos" => { ..., items[] { ..., link { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } } }, _type == "section.blog" => { ..., posts[] { ..., link { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } } }, }, footer->{ ..., links[] { ...,type == "internal" => { url->{ _type == "page" => { "slug": [pathname.current], }, },} } }, title, "slug": pathname.current, seoTitle, seoDescription, ogImage, robots, theme, } export type PAGE_BY_SLUG_QUERYResult = { _id: string; header: { @@ -777,8 +791,8 @@ export type PAGE_BY_SLUG_QUERYResult = { variant: | "badge" | "default" + | "ghost-dark" | "ghost" - | "ghostDark" | "primary" | "secondary"; size: "base" | "lg" | "sm"; @@ -786,6 +800,12 @@ export type PAGE_BY_SLUG_QUERYResult = { alignVariant: "center" | "left" | "right"; }; sectionsBody: Array< + | { + _ref: string; + _type: "reference"; + _weak?: boolean; + _key: string; + } | { _key: string; _type: "section.blog"; @@ -810,8 +830,8 @@ export type PAGE_BY_SLUG_QUERYResult = { variant: | "badge" | "default" + | "ghost-dark" | "ghost" - | "ghostDark" | "primary" | "secondary"; size: "base" | "lg" | "sm"; @@ -863,8 +883,8 @@ export type PAGE_BY_SLUG_QUERYResult = { variant: | "badge" | "default" + | "ghost-dark" | "ghost" - | "ghostDark" | "primary" | "secondary"; size: "base" | "lg" | "sm"; @@ -939,47 +959,6 @@ export type PAGE_BY_SLUG_QUERYResult = { _type: "image"; }; } - | { - _key: string; - _type: "section.hero"; - title: string; - text?: CustomRichText; - image?: CustomImage; - links: Array<{ - _key: string; - _type: "customLink"; - text: string; - type: "internal" | "url"; - href?: string; - target: "_blank" | "_parent" | "_self" | "_top"; - url: { - slug: Array; - } | null; - variant: - | "badge" - | "default" - | "ghost" - | "ghostDark" - | "primary" - | "secondary"; - size: "base" | "lg" | "sm"; - }>; - marginTop: "base" | "lg" | "none"; - marginBottom: "base" | "lg" | "none"; - maxWidth: "base" | "none" | "small"; - backgroundColor: "dark-gray" | "dark" | "light-gray" | "light" | "none"; - backgroundImage?: { - asset?: { - _ref: string; - _type: "reference"; - _weak?: boolean; - [internalGroqTypeReferenceTo]?: "sanity.imageAsset"; - }; - hotspot?: SanityImageHotspot; - crop?: SanityImageCrop; - _type: "image"; - }; - } | { _key: string; _type: "section.linksList"; @@ -996,8 +975,8 @@ export type PAGE_BY_SLUG_QUERYResult = { variant: | "badge" | "default" + | "ghost-dark" | "ghost" - | "ghostDark" | "primary" | "secondary"; size: "base" | "lg" | "sm"; @@ -1039,8 +1018,8 @@ export type PAGE_BY_SLUG_QUERYResult = { variant: | "badge" | "default" + | "ghost-dark" | "ghost" - | "ghostDark" | "primary" | "secondary"; size: "base" | "lg" | "sm"; @@ -1161,8 +1140,8 @@ export type PAGE_BY_SLUG_QUERYResult = { variant: | "badge" | "default" + | "ghost-dark" | "ghost" - | "ghostDark" | "primary" | "secondary"; size: "base" | "lg" | "sm"; diff --git a/apps/storyblok/src/app/[[...slug]]/page.tsx b/apps/storyblok/src/app/[[...slug]]/page.tsx index e841ab5..dfb94bb 100644 --- a/apps/storyblok/src/app/[[...slug]]/page.tsx +++ b/apps/storyblok/src/app/[[...slug]]/page.tsx @@ -44,9 +44,6 @@ export default async function Home({ params, searchParams }: Props) { const { story, links } = await fetchStoryBySlug( isDraftModeEnabled, params.slug, - { - resolve_relations: "header,footer", - }, ); if (!story) { diff --git a/apps/storyblok/src/components/CoreLayout/index.tsx b/apps/storyblok/src/components/CoreLayout/index.tsx index 17c9838..523c843 100644 --- a/apps/storyblok/src/components/CoreLayout/index.tsx +++ b/apps/storyblok/src/components/CoreLayout/index.tsx @@ -10,20 +10,20 @@ export default async function CoreLayout({ children, allResolvedLinks, }: ICoreLayoutProps) { - let headersAndFooters: ISbStoryData[] = []; + let globalComponentsStories: ISbStoryData[] = []; if (isDraftModeEnv) { const { data } = await fetchStoriesByParams(isDraftModeEnv, { - by_slugs: "headers/*,footers/*", + by_slugs: "components/*", }); - headersAndFooters = data; + globalComponentsStories = data; } return ( {children} diff --git a/apps/storyblok/src/components/DataContext/index.tsx b/apps/storyblok/src/components/DataContext/index.tsx index 2fb1af5..22f7b74 100644 --- a/apps/storyblok/src/components/DataContext/index.tsx +++ b/apps/storyblok/src/components/DataContext/index.tsx @@ -6,19 +6,19 @@ import type { IDataContextProviderProps, IDataContextValues } from "./types"; export const DataContext = createContext({ allResolvedLinks: [], - headersAndFooters: [], + globalComponentsStories: [], }); export function DataContextProvider({ children, allResolvedLinks, - headersAndFooters, + globalComponentsStories, }: IDataContextProviderProps) { return ( {children} diff --git a/apps/storyblok/src/components/DataContext/types.ts b/apps/storyblok/src/components/DataContext/types.ts index f66ef89..0d4b761 100644 --- a/apps/storyblok/src/components/DataContext/types.ts +++ b/apps/storyblok/src/components/DataContext/types.ts @@ -4,7 +4,7 @@ import type { IResolvedLink } from "@/lib/api"; export interface IDataContextValues { allResolvedLinks: IResolvedLink[]; - headersAndFooters: ISbStoryData[]; + globalComponentsStories: ISbStoryData[]; } export interface IDataContextProviderProps extends IDataContextValues { diff --git a/apps/storyblok/src/components/Page/index.tsx b/apps/storyblok/src/components/Page/index.tsx index e4658aa..96fcbc5 100644 --- a/apps/storyblok/src/components/Page/index.tsx +++ b/apps/storyblok/src/components/Page/index.tsx @@ -2,30 +2,25 @@ import { StoryblokComponent, StoryblokStory } from "@storyblok/react/rsc"; import { cn, CookieBanner } from "@shared/ui"; -import { useDataContext } from "../DataContext"; +import { useGlobalComponentData } from "@/lib/hooks/useGlobalComponentData"; + import type { IPageContainerProps } from "./types"; -import { getHeaderAndFooterStories } from "./utils"; export default function PageContainer({ blok }: IPageContainerProps) { - const { headersAndFooters } = useDataContext(); + const globalHeader = useGlobalComponentData(blok.header as string); + const globalFooter = useGlobalComponentData(blok.footer as string); const { sections, showCookieBanner, theme } = blok; if (!sections) return null; - const { header, footer } = getHeaderAndFooterStories( - headersAndFooters, - blok.header, - blok.footer, - ); - return (
- + {globalHeader && } {sections.map((s) => ( ))} - + {globalFooter && } {showCookieBanner && }
); diff --git a/apps/storyblok/src/components/Page/utils.ts b/apps/storyblok/src/components/Page/utils.ts deleted file mode 100644 index 5f37efe..0000000 --- a/apps/storyblok/src/components/Page/utils.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { ISbStoryData } from "@storyblok/react/rsc"; - -export function getHeaderAndFooterStories( - stories: ISbStoryData[], - header: string | ISbStoryData, - footer: string | ISbStoryData, -) { - let resolvedHeader: ISbStoryData | undefined; - let resolvedFooter: ISbStoryData | undefined; - - if (typeof header === "string") { - resolvedHeader = stories.find((s) => s.uuid === header); - } else { - resolvedHeader = header; - } - - if (typeof footer === "string") { - resolvedFooter = stories.find((s) => s.uuid === footer); - } else { - resolvedFooter = footer; - } - - return { - header: resolvedHeader, - footer: resolvedFooter, - }; -} diff --git a/apps/storyblok/src/contentSections/Hero/index.tsx b/apps/storyblok/src/contentSections/Hero/index.tsx index e57b5d1..e7b58c2 100644 --- a/apps/storyblok/src/contentSections/Hero/index.tsx +++ b/apps/storyblok/src/contentSections/Hero/index.tsx @@ -5,16 +5,38 @@ import { Hero as HeroUI } from "@shared/ui"; import { prepareImageProps } from "@/lib/adapters/prepareImageProps"; import { prepareLinkProps } from "@/lib/adapters/prepareLinkProps"; import { prepareRichTextProps } from "@/lib/adapters/prepareRichTextProps"; +import { useGlobalComponentData } from "@/lib/hooks/useGlobalComponentData"; import SectionContainer from "@/components/SectionContainer"; import type { IHeroProps } from "./types"; export default function Hero({ blok }: IHeroProps) { - const { title, text, image, links } = blok; + const { title, text, image, links, globalData } = blok; + const globalBlok = useGlobalComponentData(globalData as string); if (image.length === 0 && links.length === 0 && text?.length === 0 && !title) return ; + if (globalBlok) { + const { + title: globalTitle, + text: globalText, + image: globalImage, + links: globalLinks, + } = globalBlok.content; + + return ( + + + + ); + } + return ( | string; title?: string; text?: RichTextStoryblok[]; image: ImageStoryblok[]; diff --git a/apps/storyblok/src/lib/api.ts b/apps/storyblok/src/lib/api.ts index b447c26..183221d 100644 --- a/apps/storyblok/src/lib/api.ts +++ b/apps/storyblok/src/lib/api.ts @@ -51,7 +51,7 @@ export interface IResolvedLink { export async function fetchStoryBySlug( isDraftMode: boolean, slug: string[] = ["home"], - params?: { cv?: number; resolve_relations?: string }, + params?: { cv?: number }, ): Promise<{ story: ISbStoryData; links: IResolvedLink[] }> { const cv = await getSBcacheCVparameter(isDraftMode); @@ -69,20 +69,11 @@ export async function fetchStoryBySlug( searchParamsData as Record, ); - const { story, links, rels } = await fetch( + const { story, links } = await fetch( `${API_GATE}/stories/${slug?.join("/") || ""}?${searchParams.toString()}`, ).then((res) => res.json()); - // REST storyblok API doesnt resolve relations in the response, only uuid - // So we need to resolve them manually - // using this function it should be done automatically - if (params?.resolve_relations) { - const relations = params.resolve_relations.split(","); - - relations.forEach((relation) => { - story.content[relation] = findRelation(rels, story.content[relation]); - }); - } + console.log("links length: ", links.length); return { story, @@ -90,10 +81,6 @@ export async function fetchStoryBySlug( }; } -function findRelation(rels: any, id: string) { - return rels.find((rel: any) => rel.uuid === id); -} - // This function uses only on a build lvl to generate a sitemap export async function fetchAllPages() { const cv = await getSBcacheCVparameter(false); diff --git a/apps/storyblok/src/lib/hooks/useGlobalComponentData.tsx b/apps/storyblok/src/lib/hooks/useGlobalComponentData.tsx new file mode 100644 index 0000000..8bf40f8 --- /dev/null +++ b/apps/storyblok/src/lib/hooks/useGlobalComponentData.tsx @@ -0,0 +1,19 @@ +"use client"; + +import type { ISbStoryData } from "@storyblok/react/rsc"; + +import { useDataContext } from "@/components/DataContext"; + +export const useGlobalComponentData = ( + globalComponent: string, +): ISbStoryData | null => { + const { globalComponentsStories } = useDataContext(); + + if (!globalComponent) return null; + + const globalComponentData = globalComponentsStories.find( + (s) => s.uuid === globalComponent, + ); + + return globalComponentData || null; +}; diff --git a/packages/ui/components/sections/hero/index.tsx b/packages/ui/components/sections/hero/index.tsx index 8ba65a2..013429d 100644 --- a/packages/ui/components/sections/hero/index.tsx +++ b/packages/ui/components/sections/hero/index.tsx @@ -5,7 +5,7 @@ import type { IHeroProps } from "./types"; export function Hero({ title, text, image, links }: IHeroProps) { return ( -
+

{title}