diff --git a/src/blog/components/postCard/PostCard.tsx b/src/blog/components/postCard/PostCard.tsx index ec05efe27..2569890d1 100644 --- a/src/blog/components/postCard/PostCard.tsx +++ b/src/blog/components/postCard/PostCard.tsx @@ -1,6 +1,6 @@ "use client"; +import { SanityImage } from "src/components/image/SanityImage"; import Text from "src/components/text/Text"; -import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage"; import { Post } from "studio/lib/interfaces/pages"; import styles from "./postCard.module.css"; @@ -14,14 +14,13 @@ export const PostCard = ({ slug: string; focusRef?: React.Ref; }) => { - const renderedImage = useConvertSanityImageToNextImage(post.lead.image); const postLink = `/${slug}/${post.slug.current}`; return (
  • - {renderedImage && ( + {post.lead.image && (
    - {renderedImage} +
    )} {post.category} diff --git a/src/blog/components/postPreview/PostReview.stories.tsx b/src/blog/components/postPreview/PostPreview.stories.tsx similarity index 100% rename from src/blog/components/postPreview/PostReview.stories.tsx rename to src/blog/components/postPreview/PostPreview.stories.tsx diff --git a/src/blog/components/postPreview/PostPreview.tsx b/src/blog/components/postPreview/PostPreview.tsx index 37634a7f4..34e78284e 100644 --- a/src/blog/components/postPreview/PostPreview.tsx +++ b/src/blog/components/postPreview/PostPreview.tsx @@ -1,10 +1,10 @@ "use client"; import { PortableTextBlock } from "sanity"; +import { SanityImage } from "src/components/image/SanityImage"; import CustomLink from "src/components/link/CustomLink"; import { RichText } from "src/components/richText/RichText"; import Text from "src/components/text/Text"; -import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage"; import { LinkType } from "studio/lib/interfaces/navigation"; import { Post } from "studio/lib/interfaces/pages"; @@ -21,8 +21,6 @@ const PostPreview = ({ alignImageToRight = true, slug, }: PostPreviewProps) => { - const renderedImage = useConvertSanityImageToNextImage(post.lead.image); - const link = { _key: "string", _type: "string", @@ -60,14 +58,20 @@ const PostPreview = ({ const truncatedText = truncateFirstBlock(post.lead.richText, 400); + const hasImage = post.lead.image !== undefined; + return (
    - {renderedImage &&
    {renderedImage}
    } + {hasImage && ( +
    + +
    + )}
    {post.category} diff --git a/src/components/image/SanityImage.tsx b/src/components/image/SanityImage.tsx new file mode 100644 index 000000000..d5ba43089 --- /dev/null +++ b/src/components/image/SanityImage.tsx @@ -0,0 +1,78 @@ +"use client"; + +import { SanityImageSource } from "@sanity/image-url/lib/types/types"; +import Image from "next/image"; +import { UseNextSanityImageProps, useNextSanityImage } from "next-sanity-image"; +import { useEffect, useState } from "react"; + +import { client } from "studio/lib/client"; +import { IImage } from "studio/lib/interfaces/media"; +import { sharedClient } from "studioShared/lib/client"; + +/** + * Builds Next.js props for a given Sanity image from an unknown Sanity project. + * + * Each generated image source is checked for existence in order to pick the correct source project. + * + * NOTE: It is assumed that an image id is only valid for a single project. + * The result of providing an id that resolves to a valid image in multiple projects is therefore not well-defined. + * + * @param image asset props for image from unknown Sanity project + */ +const useNextSanityGlobalImage = ( + image: SanityImageSource, +): UseNextSanityImageProps | null => { + const studioImage = useNextSanityImage(client, image); + const sharedImage = useNextSanityImage(sharedClient, image); + + const [globalImage, setGlobalImage] = + useState(null); + + useEffect(() => { + fetch(studioImage.src).then((r) => r.ok && setGlobalImage(studioImage)); + fetch(sharedImage.src).then((r) => r.ok && setGlobalImage(sharedImage)); + }, [studioImage, sharedImage]); + + return globalImage; +}; + +const SanityAssetImage = ({ image }: { image: IImage }) => { + const imageProps = useNextSanityGlobalImage(image); + const objectPosition = image.hotspot + ? `${image.hotspot.x * 100}% ${image.hotspot.y * 100}%` + : "50% 50%"; // Default to center if no hotspot is defined + if (!imageProps) { + return null; + } + return ( + {image?.alt + ); +}; + +export function SanityImage({ image }: { image: IImage }) { + if (image?.src) { + return ( + {image?.alt + ); + } + return ; +} diff --git a/src/components/navigation/footer/Footer.tsx b/src/components/navigation/footer/Footer.tsx index 6ac67c2fe..17303cad5 100644 --- a/src/components/navigation/footer/Footer.tsx +++ b/src/components/navigation/footer/Footer.tsx @@ -2,10 +2,10 @@ import { ReactNode } from "react"; +import { SanityImage } from "src/components/image/SanityImage"; import CustomLink from "src/components/link/CustomLink"; import SoMeLink from "src/components/link/SoMeLink"; import Text from "src/components/text/Text"; -import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage"; import { BrandAssets } from "studio/lib/interfaces/brandAssets"; import { CompanyInfo } from "studio/lib/interfaces/companyDetails"; import { LegalDocument } from "studio/lib/interfaces/legalDocuments"; @@ -32,15 +32,15 @@ const Footer = ({ soMeData, legalData, }: IFooter) => { - const renderedLogo = useConvertSanityImageToNextImage( - brandAssets?.secondaryLogo, - ); - const currentYear = new Date().getFullYear(); return (