Skip to content

Commit

Permalink
feat: add article publishing information component
Browse files Browse the repository at this point in the history
  • Loading branch information
gmolki committed Nov 14, 2024
1 parent 18e9be1 commit 06c7eab
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 7 deletions.
11 changes: 6 additions & 5 deletions src/builder-registry.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { builder } from "@builder.io/react";

import "./components/BlockTag/cmp.builder";
import "./components/Blog/BlogArticleBreadcrumb/cmp.builder";
import "./components/Blog/BlogArticlePublishingInformation/cmp.builder";
import "./components/Blog/BlogArticlesGrid/cmp.builder";
import "./components/Blog/LatestBlogArticles/cmp.builder";
import "./components/Blog/HighlightedBlogArticle/cmp.builder";
import "./components/Blog/PinnedBlogArticles/cmp.builder";
import "./components/Blog/BlogBreadcrumb/cmp.builder";
import "./components/Blog/BlogCategories/cmp.builder";
import "./components/Blog/BlogCategoriesFilter/cmp.builder";
import "./components/Blog/BlogTags/cmp.builder";
import "./components/Blog/BlogTagsFilter/cmp.builder";
import "./components/Blog/CategorizationDisplayName/cmp.builder";
import "./components/Blog/BlogBreadcrumb/cmp.builder";
import "./components/Blog/BlogArticleBreadcrumb/cmp.builder";
import "./components/Blog/HighlightedBlogArticle/cmp.builder";
import "./components/Blog/LatestBlogArticles/cmp.builder";
import "./components/Blog/PinnedBlogArticles/cmp.builder";
import "./components/Box/cmp.builder";
import "./components/Breadcrumb/cmp.builder";
import "./components/BulletList/cmp.builder";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Builder } from "@builder.io/react";
import { DEFAULT_PROPS } from "@/constants/builderProps";
import { CSS_EDITABLE_INPUTS_ADVANCED } from "@/constants/builderInputs";
import BlogArticlePublishingInformation from "./cmp";

Builder.registerComponent(BlogArticlePublishingInformation, {
...DEFAULT_PROPS,
name: "Blog - Article Publishing Information",
image:
"https://cdn.builder.io/api/v1/image/assets%2Fd72545ec06f647d993e1349bf57ebd7f%2Ffd9c99abfd534bbf9ebc839eed5acfd1",
inputs: [
...DEFAULT_PROPS.inputs,
{
name: "variant",
type: "string",
defaultValue: "readTime",
enum: ["readTime", "writtenBy"],
},
],
});
81 changes: 81 additions & 0 deletions src/components/Blog/BlogArticlePublishingInformation/cmp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Image from "next/image";
import { BlogArticlePublishingInformationProps } from "./types";
import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/router";
import { fetchBuilderData } from "@/utils/fetchBuilderData";
import { buildArticleSchemaMarkup } from "@/utils/blog/buildArticleSchemaMarkup";

export const BlogArticlePublishingInformation = ({
variant,
}: BlogArticlePublishingInformationProps) => {
const router = useRouter();

const [currentPage, setCurrentPage] = useState<any>();

const articleSchemaMarkup = useMemo(
() => buildArticleSchemaMarkup(currentPage),
[currentPage]
);

useEffect(() => {
async function getCurrentBlogArticlePage() {
const page = await fetchBuilderData("get", [
"blog-article",
{
userAttributes: {
urlPath: router.asPath,
},
includeRefs: true,
},
]);

setCurrentPage(page);
}

getCurrentBlogArticlePage();
}, [router.asPath]);

if (!articleSchemaMarkup) return null;

const { author, datePublished, timeRequired } = articleSchemaMarkup;

// timeRequired is in ISO 8601 duration format (but only minutes)
const readableTimeRequired = timeRequired.match(/PT(\d+)M/)?.[1];

let title;
let subtitle;

switch (variant) {
case "readTime":
title = author.name;
subtitle = (
<>
{timeRequired ? `${readableTimeRequired} min. read` : ""}{" "}
{datePublished ? `- ${datePublished}` : ""}
</>
);
break;
case "writtenBy":
title = `Written by ${author.name}`;
subtitle = author.title;
break;
}

return (
<div tw="flex flex-row items-center gap-3">
<Image
src={author.image}
alt="Publisher"
width={32}
height={32}
tw="rounded-full"
/>
<div tw="flex flex-col justify-around">
<p className="tp-info text-base2 fs-12">{title}</p>
<p className="tp-body1 text-base2 fs-10">{subtitle}</p>
</div>
</div>
);
};

export default BlogArticlePublishingInformation;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./cmp";
3 changes: 3 additions & 0 deletions src/components/Blog/BlogArticlePublishingInformation/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type BlogArticlePublishingInformationProps = {
variant: "readTime" | "writtenBy";
};
6 changes: 4 additions & 2 deletions src/utils/blog/buildArticleSchemaMarkup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const buildArticleSchemaMarkup = (page: any) => {

const dateModified = formatDate(getField(["lastUpdated"]));
const datePublished = formatDate(getField(["firstPublished"]));
const timeRequired = `PT${getField(["data", "metadata", "timeRequired"])}M`;

return {
"@context": "https://schema.org",
Expand All @@ -34,8 +35,9 @@ export const buildArticleSchemaMarkup = (page: any) => {
image: getField(["data", "featureImage"]),
thumbnailUrl: getField(["data", "thumbnailImage"]),
dateCreated: datePublished,
datePublished: datePublished,
dateModified: dateModified,
datePublished,
dateModified,
timeRequired,
author: {
"@type": typeFromModel(page.data?.metadata?.author?.model),
...getField(["data", "metadata", "author", "value", "data"]),
Expand Down

0 comments on commit 06c7eab

Please sign in to comment.