feat: dynamic magazine category filter from published articles

Add articleCategories GraphQL query returning distinct categories from
published articles; magazine page fetches them at load time and renders
only categories that actually have content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 17:13:08 +01:00
parent 505d59b813
commit bfd058ae58
4 changed files with 42 additions and 10 deletions

View File

@@ -298,6 +298,23 @@ export async function getArticles(
});
}
const ARTICLE_CATEGORIES_QUERY = gql`
query GetArticleCategories {
articleCategories
}
`;
export async function getArticleCategories(
fetchFn?: typeof globalThis.fetch,
): Promise<string[]> {
return loggedApiCall("getArticleCategories", async () => {
const data = await getGraphQLClient(fetchFn).request<{ articleCategories: string[] }>(
ARTICLE_CATEGORIES_QUERY,
);
return data.articleCategories;
});
}
const ARTICLE_BY_SLUG_QUERY = gql`
query GetArticleBySlug($slug: String!) {
article(slug: $slug) {

View File

@@ -1,4 +1,4 @@
import { getArticles } from "$lib/services";
import { getArticles, getArticleCategories } from "$lib/services";
const LIMIT = 24;
@@ -9,6 +9,9 @@ export async function load({ fetch, url }) {
const page = Math.max(1, parseInt(url.searchParams.get("page") || "1", 10));
const offset = (page - 1) * LIMIT;
const result = await getArticles({ search, sortBy: sort, category, offset, limit: LIMIT }, fetch);
return { ...result, search, sort, category, page, limit: LIMIT };
const [result, categories] = await Promise.all([
getArticles({ search, sortBy: sort, category, offset, limit: LIMIT }, fetch),
getArticleCategories(fetch),
]);
return { ...result, search, sort, category, page, limit: LIMIT, categories };
}

View File

@@ -82,12 +82,10 @@
value={data.category ?? "all"}
options={[
{ value: "all", label: $_("magazine.categories.all") },
{ value: "photography", label: $_("magazine.categories.photography") },
{ value: "production", label: $_("magazine.categories.production") },
{ value: "interview", label: $_("magazine.categories.interview") },
{ value: "psychology", label: $_("magazine.categories.psychology") },
{ value: "trends", label: $_("magazine.categories.trends") },
{ value: "spotlight", label: $_("magazine.categories.spotlight") },
...data.categories.map((c) => ({
value: c,
label: $_(`magazine.categories.${c}`, { default: c }),
})),
]}
onchange={(v) => setParam("category", v)}
/>