Skip to content

Commit fe998f7

Browse files
authored
Merge pull request #1824 from ida-jemi/feat/reading-time-blog-cards
feat: Add reading time to blog listing cards (#1766)
2 parents 5dc319d + 6c1fe98 commit fe998f7

7 files changed

Lines changed: 76 additions & 2 deletions

File tree

docusaurus.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,4 @@ const config: Config = {
308308
},
309309
};
310310

311-
export default config;
311+
export default config;

src/components/blogCarousel/blogCard.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import React from "react";
33
import Link from "@docusaurus/Link";
44
import { getAuthorProfiles } from "../../utils/authors";
5+
import { usePluginData } from "@docusaurus/useGlobalData";
56

67
interface BlogCardProps {
78
type: string;
@@ -13,6 +14,7 @@ interface BlogCardProps {
1314
authors?: string[];
1415
tags?: string[];
1516
category?: string;
17+
readingTime?: number;
1618
}
1719

1820
const TAG_COLORS = [
@@ -48,13 +50,16 @@ const BlogCard = ({
4850
type,
4951
date,
5052
title,
53+
content,
5154
imageUrl,
5255
id,
5356
authors,
5457
tags,
5558
category,
59+
readingTime,
5660
}: BlogCardProps) => {
5761
const authorProfiles = getAuthorProfiles(authors || []);
62+
const computedReadTime = readingTime ?? 1;
5863

5964
if (!id || !type) {
6065
return <div>data not fetched properly, imageId and entryId not found</div>;
@@ -167,6 +172,24 @@ const BlogCard = ({
167172
</div>
168173
)}
169174
{date && <span className="card-date">{formatDate(date)}</span>}
175+
<span className="card-reading-time">
176+
<svg
177+
xmlns="http://www.w3.org/2000/svg"
178+
viewBox="0 0 24 24"
179+
width="11"
180+
height="11"
181+
fill="none"
182+
stroke="currentColor"
183+
strokeWidth="2"
184+
strokeLinecap="round"
185+
strokeLinejoin="round"
186+
aria-hidden="true"
187+
>
188+
<circle cx="12" cy="12" r="10" />
189+
<polyline points="12 6 12 12 16 14" />
190+
</svg>
191+
{computedReadTime} min read
192+
</span>
170193
</div>
171194
</div>
172195

src/components/blogCarousel/blogCarousel.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,4 +634,13 @@
634634
opacity: 0;
635635
transform: translateY(-20px);
636636
transition: opacity 0.4s ease-in, transform 0.4s ease-in;
637+
}
638+
/* ── Reading time ── */
639+
.card-reading-time {
640+
display: inline-flex;
641+
align-items: center;
642+
gap: 3px;
643+
font-size: 0.75rem;
644+
color: var(--ifm-color-emphasis-600);
645+
margin-top: 2px;
637646
}

src/components/blogCarousel/blogCarousel.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export function BlogCarousel() {
9090
authors={blog.authors}
9191
tags={blog.tags}
9292
category={blog.category}
93+
readingTime={blog.readingTime}
9394
/>
9495
</CarouselItem>
9596
))}

src/database/blogs/index.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface Blog {
77
authors: string[];
88
category: string;
99
tags?: string[];
10+
readingTime?: number;
1011
}
1112

1213
const blogs: Blog[] = [
@@ -18,6 +19,7 @@ const blogs: Blog[] = [
1819
description:
1920
" Are you passionate about design and dreaming of a career in it? Or maybe you are already in the design space and looking to pivot into UI/UX? ",
2021
slug: "ux-ui-design-job",
22+
readingTime: 9,
2123
authors: ["sowmiya-v", "sanjay-kv"],
2224
category: "Design",
2325
tags: ["UX", "UI", "design", "Job"],
@@ -30,6 +32,7 @@ const blogs: Blog[] = [
3032
description:
3133
"The GitHub Copilot Coding Agent is an asynchronous software engineering agent that assists developers by suggesting code snippets",
3234
slug: "git-coding-agent",
35+
readingTime: 5,
3336
authors: ["sanjay-kv"],
3437
category: "Development",
3538
tags: ["GitHub", "AI", "Coding", "Tools"],
@@ -41,6 +44,7 @@ const blogs: Blog[] = [
4144
description:
4245
"Apache Spark is a fast, open-source big data framework that leverages in-memory computing for high performance. Its architecture powers scalable distributed processing across clusters, making it essential for analytics and machine learning.",
4346
slug: "spark-architecture",
47+
readingTime: 10,
4448
authors: ["Aditya-Singh-Rathore", "sanjay-kv"],
4549
category: "Development",
4650
tags: ["Apache Spark", "Big Data", "Data Engineering", "Architecture"],
@@ -52,6 +56,7 @@ const blogs: Blog[] = [
5256
description:
5357
"N8N is an open-source workflow automation tool that enables users to connect various apps and services to automate tasks without extensive coding knowledge.",
5458
slug: "n8n-workflow-automation",
59+
readingTime: 10,
5560
authors: ["Aditya-Singh-Rathore"],
5661
category: "Development",
5762
tags: ["Automation", "Workflow", "N8N", "Tools"],
@@ -63,6 +68,7 @@ const blogs: Blog[] = [
6368
description:
6469
"OpenAI AgentKit is a framework that simplifies the process of building AI agents, allowing developers to create intelligent applications without getting bogged down in the underlying complexities.",
6570
slug: "open-ai-agent-builder",
71+
readingTime: 14,
6672
authors: ["Aditya-Singh-Rathore"],
6773
category: "AI & Tech",
6874
tags: ["AI", "OpenAI", "Development", "Agents"],
@@ -74,6 +80,7 @@ const blogs: Blog[] = [
7480
description:
7581
"Delta Lake is an open-source storage layer that brings ACID transactions to Apache Spark and big data workloads.",
7682
slug: "deltalake-data-storage",
83+
readingTime: 7,
7784
authors: ["Aditya-Singh-Rathore"],
7885
category: "data engineering",
7986
tags: ["Delta Lake", "Big Data", "Data Engineering", "Storage"],
@@ -85,6 +92,7 @@ const blogs: Blog[] = [
8592
description:
8693
"The Microsoft Certified: Azure Data Engineer Associate certification validates your skills in designing and implementing data solutions on the Azure platform.",
8794
slug: "fabric-data-engineer",
95+
readingTime: 7,
8896
authors: ["Aditya-Singh-Rathore"],
8997
category: "data engineering",
9098
tags: ["Microsoft", "Azure", "Data Engineering", "Certification"],
@@ -96,6 +104,7 @@ const blogs: Blog[] = [
96104
description:
97105
"Microsoft Fabric is a unified analytics platform that integrates various data services and tools to provide a seamless experience for data professionals, enabling them to manage and analyze data across the entire data lifecycle.",
98106
slug: "microsoft-fabric-explained",
107+
readingTime: 10,
99108
authors: ["Aditya-Singh-Rathore"],
100109
category: "data engineering",
101110
tags: ["Microsoft", "Azure", "Data Engineering", "Certification", "Fabric", "OneLake", "Data Workloads", "Unified Analytics"],
@@ -107,6 +116,7 @@ const blogs: Blog[] = [
107116
description:
108117
"SSO lets you log into dozens of apps with a single set of credentials. But how does it actually work under the hood? A beginner-friendly walkthrough of the full flow — from clicking 'Sign in with Google' to getting access — step by step.",
109118
slug: "single-sign-on",
119+
readingTime: 6,
110120
authors: ["Aditya-Singh-Rathore", "sanjay-kv"],
111121
category: "security",
112122
tags: ["SSO", "Authentication", "Security", "OAuth", "OpenID Connect", "SAML"],
@@ -118,6 +128,7 @@ const blogs: Blog[] = [
118128
description:
119129
"Lakehouse and Data Warehouse are two different data storage architectures. A Data Warehouse is a centralized repository for structured data, optimized for reporting and analysis. A Lakehouse combines the best of both worlds, allowing for the storage of both structured and unstructured data, providing flexibility and scalability.",
120130
slug: "lakehouse-vs-warehouse",
131+
readingTime: 7,
121132
authors: ["Aditya-Singh-Rathore"],
122133
category: "data engineering",
123134
tags: ["Lakehouse", "Data Warehouse", "Data Storage", "Big Data", "Architecture", "Comparison"],
@@ -129,6 +140,7 @@ const blogs: Blog[] = [
129140
description:
130141
"Netflix processes an enormous amount of data every day, handling over 2 trillion events. This article explores how they manage this massive scale and the technologies they use to ensure smooth operations.",
131142
slug: "netflix-data-engineering",
143+
readingTime: 15,
132144
authors: ["Aditya-Singh-Rathore"],
133145
category: "data engineering",
134146
tags: ["Netflix", "Data Processing", "Big Data", "Scalability", "Event Handling", "Technology", "Architecture", "Data Engineering"],
@@ -140,6 +152,7 @@ const blogs: Blog[] = [
140152
description:
141153
"Azure Storage and Azure Data Lake Storage Gen2 (ADLS Gen2) are two different storage solutions offered by Microsoft Azure. Azure Storage is a general-purpose storage service that provides various types of storage, including blobs, files, queues, and tables. ADLS Gen2, on the other hand, is a specialized storage solution designed for big data analytics workloads, offering features like hierarchical namespace and optimized performance for analytics.",
142154
slug: "azure-storage-options",
155+
readingTime: 14,
143156
authors: ["Aditya-Singh-Rathore"],
144157
category: "data engineering",
145158
tags: ["Azure", "Storage", "Data Lake", "ADLS Gen2", "Big Data", "Scalability", "Event Handling", "Technology", "Architecture", "Data Engineering"],
@@ -151,6 +164,7 @@ const blogs: Blog[] = [
151164
description:
152165
"Azure Data Factory Pipeline is a cloud-based data integration service that allows you to create data-driven workflows for orchestrating and automating data movement and transformation tasks. This article will guide you through the process of building your first ETL pipeline in Azure Data Factory.",
153166
slug: "ETL-pipeline-tutorial",
167+
readingTime: 11,
154168
authors: ["Aditya-Singh-Rathore"],
155169
category: "data engineering",
156170
tags: ["Azure", "Storage", "Data Lake", "ADLS Gen2", "Big Data", "Scalability", "Event Handling", "Technology", "Architecture", "Data Engineering"],
@@ -162,6 +176,7 @@ const blogs: Blog[] = [
162176
description:
163177
"The Medallion Architecture is a data management approach that organizes data into different layers (Bronze, Silver, Gold) to improve data quality, governance, and scalability in data pipelines. It helps prevent data pipelines from becoming unmanageable by providing a structured framework for data processing and storage.",
164178
slug: "medallion-architecture",
179+
readingTime: 9,
165180
authors: ["Aditya-Singh-Rathore"],
166181
category: "data engineering",
167182
tags: ["Medallion Architecture", "Data Pipeline", "Data Management", "Data Quality", "Data Governance", "Scalability", "Data Engineering"],
@@ -173,6 +188,7 @@ const blogs: Blog[] = [
173188
description:
174189
"Azure Synapse Analytics is a unified analytics service that combines big data and data warehousing capabilities. This article explores when to use Azure Synapse Analytics and when to choose Fabric instead.",
175190
slug: "azure-synapse-analytics",
191+
readingTime: 13,
176192
authors: ["Aditya-Singh-Rathore"],
177193
category: "data engineering",
178194
tags: ["Azure", "Synapse Analytics", "Data Warehousing", "Big Data", "Unified Analytics", "Fabric", "Data Engineering"],
@@ -184,6 +200,7 @@ const blogs: Blog[] = [
184200
description:
185201
"Streaming pipelines are powerful for real-time data processing, but they come with hidden costs that are often overlooked. These costs include increased complexity, higher resource consumption, and potential challenges in maintaining data consistency and reliability. This article explores these hidden costs and provides insights on how to mitigate them.",
186202
slug: "batch-vs-stream-processing",
203+
readingTime: 10,
187204
authors: ["Aditya-Singh-Rathore"],
188205
category: "data engineering",
189206
tags: ["Streaming Pipelines", "Real-Time Data Processing", "Data Consistency", "Data Reliability", "Resource Consumption", "Complexity", "Data Engineering"],
@@ -196,6 +213,7 @@ const blogs: Blog[] = [
196213
description:
197214
"Azure Data Pipeline can be a powerful tool for data processing and analytics, but it can also lead to unexpectedly high costs if not managed properly. In this article, we share our experience of optimizing our Azure Data Pipeline costs, which resulted in a 73% reduction in our monthly bill, saving us $3,066. We discuss the strategies we implemented to achieve this significant cost reduction while maintaining the performance and reliability of our data pipeline.",
198215
slug: "azure-cost-optimization",
216+
readingTime: 19,
199217
authors: ["Aditya-Singh-Rathore"],
200218
category: "data engineering",
201219
tags: ["Azure", "Data Pipeline", "Cost Optimization", "Data Engineering"],
@@ -207,6 +225,7 @@ const blogs: Blog[] = [
207225
description:
208226
"PySpark is a powerful tool for big data processing, but it can be challenging to optimize for performance. In this article, we discuss six common mistakes that beginners make when optimizing their PySpark pipelines, which can lead to slow performance and increased costs. We provide practical tips and techniques to help you avoid these pitfalls and improve the efficiency of your PySpark applications.",
209227
slug: "spark-performance-optimizations",
228+
readingTime: 27,
210229
authors: ["Aditya-Singh-Rathore"],
211230
category: "data engineering",
212231
tags: ["PySpark", "Optimization", "Big Data", "Performance", "Data Engineering"],
@@ -218,6 +237,7 @@ const blogs: Blog[] = [
218237
description:
219238
"Microsoft Purview Data Catalog is a powerful tool for managing and organizing data assets within an organization. In this article, we share our experience of using Purview Data Catalog to streamline the onboarding process for new data engineers, reducing the time it takes from 2 weeks to just 3 days. We discuss the features of Purview that enabled us to achieve this improvement and provide insights on how other organizations can leverage this tool to enhance their data management practices.",
220239
slug: "microsoft-data-purview",
240+
readingTime: 19,
221241
authors: ["Aditya-Singh-Rathore"],
222242
category: "data engineering",
223243
tags: ["Purview", "Data Catalog", "Onboarding", "Data Management", "Data Engineering"],
@@ -229,6 +249,7 @@ const blogs: Blog[] = [
229249
description:
230250
"Data engineers often have a deeper understanding of data and its implications for business decisions than MBAs, who may focus more on theory and strategy. This article explores why data engineers can make better business analysts than MBAs, highlighting their technical expertise, problem-solving skills, and ability to derive insights from data to drive informed business decisions.",
231251
slug: "data-engineers-vs-mbas",
252+
readingTime: 18,
232253
authors: ["Aditya-Singh-Rathore"],
233254
category: "data engineering",
234255
tags: ["Data Engineers", "Business Analysts", "MBAs", "Data Understanding", "Business Decisions"],
@@ -240,6 +261,7 @@ const blogs: Blog[] = [
240261
description:
241262
" Google has unveiled a new icon design that reflects its commitment to simplicity and accessibility. The updated icon features a more modern ",
242263
slug: "google-icon-update",
264+
readingTime: 8,
243265
authors: ["sanjay-kv"],
244266
category: "Design",
245267
tags: ["UX", "UI", "design", "Job"],
@@ -249,4 +271,4 @@ const blogs: Blog[] = [
249271

250272
];
251273

252-
export default blogs;
274+
export default blogs;

src/pages/blogs/blogs-new.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,4 +1304,13 @@
13041304
padding: 0 18px;
13051305
font-size: 13px;
13061306
}
1307+
}
1308+
/* ── Reading time ── */
1309+
.card-reading-time {
1310+
display: inline-flex;
1311+
align-items: center;
1312+
gap: 3px;
1313+
font-size: 0.75rem;
1314+
color: var(--ifm-color-emphasis-600);
1315+
margin-top: 2px;
13071316
}

src/pages/blogs/index.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ export default function Blogs() {
232232
// ─── BlogCard ────────────────────────────────────────────────────────────────
233233

234234
const BlogCard = ({ blog }: { blog: (typeof blogs)[number] }) => {
235+
const readingTime = blog.readingTime ?? 1;
235236
const authors = getAuthorProfiles(blog.authors || []);
236237

237238
// Tags — use blog.tags if present, fallback to blog.category as single tag
@@ -350,6 +351,15 @@ const BlogCard = ({ blog }: { blog: (typeof blogs)[number] }) => {
350351
{(blog as any).date && (
351352
<span className="card-date">{formatDate((blog as any).date)}</span>
352353
)}
354+
<span className="card-reading-time">
355+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="11" height="11"
356+
fill="none" stroke="currentColor" strokeWidth="2"
357+
strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
358+
<circle cx="12" cy="12" r="10" />
359+
<polyline points="12 6 12 12 16 14" />
360+
</svg>
361+
{readingTime} min read
362+
</span>
353363
</div>
354364
</div>
355365

0 commit comments

Comments
 (0)