feat: complete MDX migration for blog, fix diagram fidelity and refactor styling architecture
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { ImageResponse } from "next/og";
|
||||
import { blogPosts } from "../../../src/data/blogPosts";
|
||||
import { blogThumbnails } from "../../../src/data/blogThumbnails";
|
||||
import { allPosts } from "contentlayer/generated";
|
||||
import { blogThumbnails } from "../../../src/components/blog/blogThumbnails";
|
||||
import { OGImageTemplate } from "../../../src/components/OGImageTemplate";
|
||||
import { getOgFonts, OG_IMAGE_SIZE } from "../../../src/lib/og-helper";
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function Image({
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
const { slug } = await params;
|
||||
const post = blogPosts.find((p) => p.slug === slug);
|
||||
const post = allPosts.find((p) => p.slug === slug);
|
||||
const thumbnail = blogThumbnails[slug];
|
||||
|
||||
const title = post?.title || "Marc Mintel";
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import * as React from "react";
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { blogPosts } from "../../../src/data/blogPosts";
|
||||
import { allPosts } from "contentlayer/generated";
|
||||
import { BlogPostHeader } from "../../../src/components/blog/BlogPostHeader";
|
||||
import { Section } from "../../../src/components/Section";
|
||||
import { Reveal } from "../../../src/components/Reveal";
|
||||
import { BlogPostClient } from "../../../src/components/BlogPostClient";
|
||||
import { PostComponents } from "../../../src/components/blog/posts";
|
||||
import { TextSelectionShare } from "../../../src/components/TextSelectionShare";
|
||||
import { BlogPostStickyBar } from "../../../src/components/blog/BlogPostStickyBar";
|
||||
import { MDXRemote } from "next-mdx-remote/rsc";
|
||||
import { MDXComponents } from "../../../mdx-components";
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return blogPosts.map((post) => ({
|
||||
return allPosts.map((post) => ({
|
||||
slug: post.slug,
|
||||
}));
|
||||
}
|
||||
@@ -22,7 +23,7 @@ export async function generateMetadata({
|
||||
params: Promise<{ slug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const post = blogPosts.find((p) => p.slug === slug);
|
||||
const post = allPosts.find((p) => p.slug === slug);
|
||||
|
||||
if (!post) return {};
|
||||
|
||||
@@ -48,7 +49,7 @@ export default async function BlogPostPage({
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
const { slug } = await params;
|
||||
const post = blogPosts.find((p) => p.slug === slug);
|
||||
const post = allPosts.find((p) => p.slug === slug);
|
||||
|
||||
if (!post) {
|
||||
notFound();
|
||||
@@ -60,11 +61,9 @@ export default async function BlogPostPage({
|
||||
year: "numeric",
|
||||
});
|
||||
|
||||
const wordCount = post.description.split(/\s+/).length + 300; // Average post length
|
||||
const wordCount = post.description.split(/\s+/).length + 300;
|
||||
const readingTime = Math.max(1, Math.ceil(wordCount / 200));
|
||||
|
||||
const PostContent = PostComponents[slug];
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-8 md:gap-12 py-8 md:py-24 overflow-hidden">
|
||||
<BlogPostClient readingTime={readingTime} title={post.title} />
|
||||
@@ -78,7 +77,6 @@ export default async function BlogPostPage({
|
||||
/>
|
||||
|
||||
<main id="post-content">
|
||||
{/* Sticky Progress Bar */}
|
||||
<BlogPostStickyBar
|
||||
title={post.title}
|
||||
url={`https://mintel.me/blog/${slug}`}
|
||||
@@ -89,7 +87,7 @@ export default async function BlogPostPage({
|
||||
<Reveal delay={0.4} width="100%">
|
||||
{post.tags && post.tags.length > 0 && (
|
||||
<div className="flex flex-wrap gap-2 mb-10 md:mb-12">
|
||||
{post.tags.map((tag, index) => (
|
||||
{post.tags?.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-2.5 py-1 bg-slate-50 border border-slate-100 rounded text-[9px] md:text-[10px] font-mono text-slate-500 uppercase tracking-widest"
|
||||
@@ -100,13 +98,12 @@ export default async function BlogPostPage({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{PostContent ? (
|
||||
<PostContent />
|
||||
) : (
|
||||
<div className="p-8 bg-slate-50 border border-slate-200 rounded-lg italic text-slate-500">
|
||||
Inhalt wird bald veröffentlicht...
|
||||
</div>
|
||||
)}
|
||||
<div className="max-w-none">
|
||||
<MDXRemote
|
||||
source={post.body.raw.replace(/^---[\s\S]*?\n---\s*/, '')}
|
||||
components={MDXComponents}
|
||||
/>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as React from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { MediumCard } from "../../src/components/MediumCard";
|
||||
import { BlogCommandBar } from "../../src/components/blog/BlogCommandBar";
|
||||
import { blogPosts } from "../../src/data/blogPosts";
|
||||
import { allPosts as contentPosts } from "contentlayer/generated";
|
||||
import { SectionHeader } from "../../src/components/SectionHeader";
|
||||
import { Reveal } from "../../src/components/Reveal";
|
||||
import { Section } from "../../src/components/Section";
|
||||
@@ -19,7 +19,7 @@ export default function BlogPage() {
|
||||
// Memoize allPosts
|
||||
const allPosts = React.useMemo(
|
||||
() =>
|
||||
[...blogPosts].sort(
|
||||
[...contentPosts].sort(
|
||||
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
|
||||
),
|
||||
[],
|
||||
|
||||
Reference in New Issue
Block a user