feat: add author pages at /author/:authorSlug with clickable author names in posts

Add author archive pages displaying all posts by a specific author, following
  the existing tag pages pattern. Author names in post headers are now clickable
  links that navigate to the author's page.

  Changes:
  - Add by_authorName index to posts table (convex/schema.ts)
  - Add getAllAuthors and getPostsByAuthor queries (convex/posts.ts)
  - Create AuthorPage.tsx component with list/cards view toggle
  - Add /author/:authorSlug route (src/App.tsx)
  - Make authorName clickable in Post.tsx for posts and pages
  - Add author link and page styles (src/styles/global.css)
  - Add author pages to sitemap (convex/http.ts)
  - Update documentation: files.md, TASK.md, changelog.md, changelog-page.md
  - Save implementation plan to prds/authorname-blogs.md
This commit is contained in:
Wayne Sutton
2026-01-01 00:05:10 -08:00
parent 1e759495eb
commit 1eaec05fec
18 changed files with 899 additions and 6 deletions

View File

@@ -0,0 +1,28 @@
import { TextAa } from "@phosphor-icons/react";
import { useFont } from "../context/FontContext";
export default function FontToggle() {
const { fontFamily, toggleFontFamily } = useFont();
const getLabel = () => {
switch (fontFamily) {
case "serif":
return "Serif";
case "sans":
return "Sans";
case "monospace":
return "Mono";
}
};
return (
<button
className="font-toggle"
onClick={toggleFontFamily}
aria-label={`Font: ${getLabel()}. Click to change.`}
title={`Font: ${getLabel()}`}
>
<TextAa size={18} />
</button>
);
}

View File

@@ -4,6 +4,7 @@ import { useQuery } from "convex/react";
import { api } from "../../convex/_generated/api";
import { MagnifyingGlass } from "@phosphor-icons/react";
import ThemeToggle from "./ThemeToggle";
import FontToggle from "./FontToggle";
import SearchModal from "./SearchModal";
import MobileMenu, { HamburgerButton } from "./MobileMenu";
import ScrollToTop, { ScrollToTopConfig } from "./ScrollToTop";
@@ -165,6 +166,8 @@ export default function Layout({ children }: LayoutProps) {
>
<MagnifyingGlass size={18} weight="bold" />
</button>
{/* Font toggle */}
<FontToggle />
{/* Theme toggle */}
<div className="theme-toggle-container">
<ThemeToggle />
@@ -196,6 +199,8 @@ export default function Layout({ children }: LayoutProps) {
>
<MagnifyingGlass size={18} weight="bold" />
</button>
{/* Font toggle */}
<FontToggle />
{/* Theme toggle */}
<div className="theme-toggle-container">
<ThemeToggle />