From eb16815f911884b5db5d0cf3d77ea6c6344366e5 Mon Sep 17 00:00:00 2001 From: bunker-admin Date: Fri, 27 Mar 2026 13:33:47 -0600 Subject: [PATCH] Fix blog hooks: unwrap API response envelope for authors and categories The API returns { authors: {...} } and { categories: [...] } but hooks were expecting the unwrapped values directly. Also add defensive guards in components for undefined props during initial render. Bunker Admin --- admin/src/components/docs/BlogFrontmatterPanel.tsx | 4 ++-- admin/src/components/docs/NewBlogPostModal.tsx | 4 ++-- admin/src/hooks/useBlogAuthors.ts | 4 ++-- admin/src/hooks/useBlogCategories.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/admin/src/components/docs/BlogFrontmatterPanel.tsx b/admin/src/components/docs/BlogFrontmatterPanel.tsx index ec857447..d714c1e3 100644 --- a/admin/src/components/docs/BlogFrontmatterPanel.tsx +++ b/admin/src/components/docs/BlogFrontmatterPanel.tsx @@ -42,12 +42,12 @@ export function BlogFrontmatterPanel({ if (!frontmatter) return null; - const authorOptions = Object.entries(authors).map(([key, entry]) => ({ + const authorOptions = Object.entries(authors || {}).map(([key, entry]) => ({ label: entry.name, value: key, })); - const categoryOptions = categories.map((cat) => ({ + const categoryOptions = (categories || []).map((cat) => ({ label: cat, value: cat, })); diff --git a/admin/src/components/docs/NewBlogPostModal.tsx b/admin/src/components/docs/NewBlogPostModal.tsx index cb55aca0..c1c00a3b 100644 --- a/admin/src/components/docs/NewBlogPostModal.tsx +++ b/admin/src/components/docs/NewBlogPostModal.tsx @@ -42,12 +42,12 @@ export function NewBlogPostModal({ const dateStr = dateValue ? dateValue.format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD'); const previewFilename = slug ? `blog/posts/${dateStr}-${slug}.md` : ''; - const authorOptions = Object.entries(authors).map(([key, entry]) => ({ + const authorOptions = Object.entries(authors || {}).map(([key, entry]) => ({ label: entry.name, value: key, })); - const categoryOptions = categories.map((cat) => ({ + const categoryOptions = (categories || []).map((cat) => ({ label: cat, value: cat, })); diff --git a/admin/src/hooks/useBlogAuthors.ts b/admin/src/hooks/useBlogAuthors.ts index 2cfb980a..beb72b78 100644 --- a/admin/src/hooks/useBlogAuthors.ts +++ b/admin/src/hooks/useBlogAuthors.ts @@ -29,8 +29,8 @@ export function useBlogAuthors(): UseBlogAuthorsReturn { const refetch = useCallback(async () => { setLoading(true); try { - const res = await api.get('/docs/blog/authors'); - setAuthors(res.data); + const res = await api.get<{ authors: AuthorsMap }>('/docs/blog/authors'); + setAuthors(res.data.authors ?? {}); } catch { // If no authors file exists yet, keep empty setAuthors({}); diff --git a/admin/src/hooks/useBlogCategories.ts b/admin/src/hooks/useBlogCategories.ts index de103c9d..b02481f3 100644 --- a/admin/src/hooks/useBlogCategories.ts +++ b/admin/src/hooks/useBlogCategories.ts @@ -14,8 +14,8 @@ export function useBlogCategories(): UseBlogCategoriesReturn { const refetch = useCallback(async () => { setLoading(true); try { - const res = await api.get('/docs/blog/categories'); - setCategories(res.data); + const res = await api.get<{ categories: string[] }>('/docs/blog/categories'); + setCategories(res.data.categories ?? []); } catch { setCategories([]); } finally {