From 0b9c486ecf47d84ff652b541b9716d28e3fd3513 Mon Sep 17 00:00:00 2001 From: Xuban <59646791+EHxuban11@users.noreply.github.com> Date: Mon, 29 Jun 2026 00:05:59 +0200 Subject: [PATCH 01/10] Add Models index, Articles section, and homepage benchmark-run badge - Models (/models): families grouped by architecture (CNN vs DETR), each links to its existing (previously unlinked) family page - Articles (/articles): in-shell section + one sample article that embeds a live verified chart; MDX-ready content registry - Homepage: shields-style Benchmark runs badge from the verified dataset; reframe as LibreYOLO's board and drop the 'most models' hedge - Nav adds Models + Articles; pin turbopack.root to stop stray home-dir lockfiles misdirecting Next's workspace root --- website/next.config.ts | 7 + website/src/app/articles/[slug]/page.tsx | 193 ++++++++++++++++++ website/src/app/articles/page.tsx | 93 +++++++++ website/src/app/layout.tsx | 4 + website/src/app/models/page.tsx | 175 ++++++++++++++++ website/src/app/page.tsx | 24 ++- .../leaderboard/LeaderboardDashboard.tsx | 2 +- website/src/config/site.ts | 2 + website/src/lib/articles.ts | 74 +++++++ website/src/lib/data/fetcher.ts | 9 +- website/src/lib/data/loader.ts | 16 ++ 11 files changed, 594 insertions(+), 5 deletions(-) create mode 100644 website/src/app/articles/[slug]/page.tsx create mode 100644 website/src/app/articles/page.tsx create mode 100644 website/src/app/models/page.tsx create mode 100644 website/src/lib/articles.ts diff --git a/website/next.config.ts b/website/next.config.ts index fa09489..12147a7 100644 --- a/website/next.config.ts +++ b/website/next.config.ts @@ -1,6 +1,13 @@ import type { NextConfig } from "next"; +import path from "path"; const nextConfig: NextConfig = { + // Pin the workspace root to this app. Stray package-lock.json files higher up + // (e.g. in the home directory) otherwise make Next infer the wrong root, which + // breaks module resolution and makes the watcher scan the whole home tree. + turbopack: { + root: path.resolve(__dirname), + }, async redirects() { return [ { diff --git a/website/src/app/articles/[slug]/page.tsx b/website/src/app/articles/[slug]/page.tsx new file mode 100644 index 0000000..4c386cb --- /dev/null +++ b/website/src/app/articles/[slug]/page.tsx @@ -0,0 +1,193 @@ +import { Metadata } from "next"; +import Link from "next/link"; +import { notFound } from "next/navigation"; +import { ArrowLeft } from "lucide-react"; +import { getArticle, publishedArticles, formatArticleDate } from "@/lib/articles"; +import { siteConfig } from "@/config/site"; + +interface Props { + params: Promise<{ slug: string }>; +} + +export function generateStaticParams() { + return publishedArticles().map((a) => ({ slug: a.slug })); +} + +export async function generateMetadata({ params }: Props): Promise { + const { slug } = await params; + const article = getArticle(slug); + if (!article) return { title: "Article Not Found" }; + return { + title: article.title, + description: article.dek, + openGraph: { + title: `${article.title} | ${siteConfig.name}`, + description: article.dek, + type: "article", + }, + }; +} + +// v1 proposal: bodies are React so they can embed live charts. In production this +// map is replaced by MDX files under content/articles, same metadata + body shape. +const BODIES: Record React.ReactNode> = { + "yolov9s-vs-yolox-s": Yolov9sVsYoloxS, +}; + +export default async function ArticlePage({ params }: Props) { + const { slug } = await params; + const article = getArticle(slug); + const Body = BODIES[slug]; + + if (!article || article.status !== "published" || !Body) { + notFound(); + return null; + } + + return ( + <> +
+
+ + + All articles + +
+ {article.tags.slice(0, 3).join(" · ")} +
+

{article.title}

+

{article.dek}

+
+ {article.author} · {formatArticleDate(article.date)} · {article.readingMinutes} min read +
+
+
+ +
+
+ +
+
+ + ); +} + +function ProposalNote() { + return ( +

+ Proposal preview. The layout and voice are the proposed final form; the chart below is live, + verified data. In production the prose figures are pulled from the same dataset through the + article fact-sheet, so nothing here is hand-typed. +

+ ); +} + +function LiveChart({ + src, + caption, + height = 460, +}: { + src: string; + caption: string; + height?: number; +}) { + return ( +
+
+ + Live chart + + verified data +
+