/ concept-collection / benchcompress
Sign in
concept-collection / benchcompress
benchcompress / web-ui / src / hooks / useMarkdownPosts.ts
62 lines · 1.9 KBCodeBlameHistory
2f82381Update benchmark results from 2025-07-24 16:44:35 [skip ci]GitHub Actions Bot 1import { useState, useEffect } from "react";
3interface Post {
4 path: string;
5 content: string;
6 date: Date;
7}
9export const useMarkdownPosts = (directory: string) => {
10 const [posts, setPosts] = useState<Post[]>([]);
11 const [error, setError] = useState<string | null>(null);
12 const [loading, setLoading] = useState(true);
14 useEffect(() => {
15 const fetchPosts = async () => {
16 try {
17 // First fetch the index
18 const indexResponse = await fetch(`${directory}/index.txt`);
19 if (!indexResponse.ok) {
20 throw new Error(
21 `Failed to load post index: ${indexResponse.statusText}`,
22 );
23 }
24 const indexContent = await indexResponse.text();
25 const paths = indexContent.trim().split("\n");
27 // Then fetch all posts in parallel
28 const postPromises = paths.map(async (path) => {
29 const response = await fetch(`${directory}/${path}`);
30 if (!response.ok) {
31 throw new Error(
32 `Failed to load post ${path}: ${response.statusText}`,
33 );
34 }
35 const content = await response.text();
37 // Parse date from filename (format: YYYY-MM-DD-title.md)
38 const dateMatch = path.match(/^(\d{4}-\d{2}-\d{2})/);
39 if (!dateMatch) {
40 throw new Error(`Invalid post filename format: ${path}`);
41 }
42 const date = new Date(dateMatch[1]);
44 return { path, content, date };
45 });
47 const loadedPosts = await Promise.all(postPromises);
48 // Sort posts by date, newest first
49 loadedPosts.sort((a, b) => b.date.getTime() - a.date.getTime());
50 setPosts(loadedPosts);
51 setLoading(false);
52 } catch (err) {
53 setError(err instanceof Error ? err.message : "Failed to load posts");
54 setLoading(false);
55 }
56 };
58 fetchPosts();
59 }, [directory]);
61 return { posts, error, loading };
62};
moveopenescclose