mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
feat: add featured section, logo gallery, Firecrawl import, and API export
Featured Section - Frontmatter-controlled featured items with featured: true and featuredOrder - Card view with excerpts and list/card toggle button - View preference saved to localStorage - New Convex queries for featured posts and pages with by_featured index Logo Gallery - Continuous marquee scroll with clickable logos - CSS animation, grayscale with color on hover - Configurable speed, position, and title - 5 sample logos included Firecrawl Content Importer - npm run import <url> scrapes external URLs to markdown drafts - Creates local files in content/blog/ with frontmatter - Then sync to dev or prod (no separate import:prod command) API Enhancements - New /api/export endpoint for batch content fetching - AI plugin discovery at /.well-known/ai-plugin.json - OpenAPI 3.0 spec at /openapi.yaml - Enhanced llms.txt documentation Documentation - AGENTS.md with codebase instructions for AI agents - Updated all sync vs deploy tables to include import workflow - Renamed content/pages/changelog.md to changelog-page.md Technical - New components: FeaturedCards.tsx, LogoMarquee.tsx - New script: scripts/import-url.ts - New dependency: @mendable/firecrawl-js - Schema updates with featured, featuredOrder, excerpt fields
This commit is contained in:
@@ -30,6 +30,9 @@ interface PostFrontmatter {
|
||||
tags: string[];
|
||||
readTime?: string;
|
||||
image?: string; // Header/OG image URL
|
||||
excerpt?: string; // Short excerpt for card view
|
||||
featured?: boolean; // Show in featured section
|
||||
featuredOrder?: number; // Order in featured section (lower = first)
|
||||
}
|
||||
|
||||
interface ParsedPost {
|
||||
@@ -42,6 +45,9 @@ interface ParsedPost {
|
||||
tags: string[];
|
||||
readTime?: string;
|
||||
image?: string; // Header/OG image URL
|
||||
excerpt?: string; // Short excerpt for card view
|
||||
featured?: boolean; // Show in featured section
|
||||
featuredOrder?: number; // Order in featured section (lower = first)
|
||||
}
|
||||
|
||||
// Page frontmatter (for static pages like About, Projects, Contact)
|
||||
@@ -50,6 +56,9 @@ interface PageFrontmatter {
|
||||
slug: string;
|
||||
published: boolean;
|
||||
order?: number; // Display order in navigation
|
||||
excerpt?: string; // Short excerpt for card view
|
||||
featured?: boolean; // Show in featured section
|
||||
featuredOrder?: number; // Order in featured section (lower = first)
|
||||
}
|
||||
|
||||
interface ParsedPage {
|
||||
@@ -58,6 +67,9 @@ interface ParsedPage {
|
||||
content: string;
|
||||
published: boolean;
|
||||
order?: number;
|
||||
excerpt?: string; // Short excerpt for card view
|
||||
featured?: boolean; // Show in featured section
|
||||
featuredOrder?: number; // Order in featured section (lower = first)
|
||||
}
|
||||
|
||||
// Calculate reading time based on word count
|
||||
@@ -92,6 +104,9 @@ function parseMarkdownFile(filePath: string): ParsedPost | null {
|
||||
tags: frontmatter.tags || [],
|
||||
readTime: frontmatter.readTime || calculateReadTime(content),
|
||||
image: frontmatter.image, // Header/OG image URL
|
||||
excerpt: frontmatter.excerpt, // Short excerpt for card view
|
||||
featured: frontmatter.featured, // Show in featured section
|
||||
featuredOrder: frontmatter.featuredOrder, // Order in featured section
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Error parsing ${filePath}:`, error);
|
||||
@@ -135,6 +150,9 @@ function parsePageFile(filePath: string): ParsedPage | null {
|
||||
content: content.trim(),
|
||||
published: frontmatter.published ?? true,
|
||||
order: frontmatter.order,
|
||||
excerpt: frontmatter.excerpt, // Short excerpt for card view
|
||||
featured: frontmatter.featured, // Show in featured section
|
||||
featuredOrder: frontmatter.featuredOrder, // Order in featured section
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Error parsing page ${filePath}:`, error);
|
||||
|
||||
Reference in New Issue
Block a user