chrysopedia/frontend/src/api/topics.ts
jlightner dbc4afcf42 feat: Normalized /topics and /videos endpoints from bare lists to pagin…
- "backend/schemas.py"
- "backend/routers/topics.py"
- "backend/routers/videos.py"
- "frontend/src/api/topics.ts"
- "frontend/src/pages/TopicsBrowse.tsx"
- "frontend/src/pages/Home.tsx"

GSD-Task: S05/T03
2026-04-03 23:09:33 +00:00

42 lines
1.5 KiB
TypeScript

import { request, BASE } from "./client";
import type { TechniqueListResponse } from "./techniques";
// ── Types ────────────────────────────────────────────────────────────────────
export interface TopicSubTopic {
name: string;
technique_count: number;
creator_count: number;
}
export interface TopicCategory {
name: string;
description: string;
sub_topics: TopicSubTopic[];
}
export interface TopicListResponse {
items: TopicCategory[];
total: number;
}
// ── Functions ────────────────────────────────────────────────────────────────
export async function fetchTopics(): Promise<TopicListResponse> {
return request<TopicListResponse>(`${BASE}/topics`);
}
export async function fetchSubTopicTechniques(
categorySlug: string,
subtopicSlug: string,
params: { limit?: number; offset?: number; sort?: string } = {},
): Promise<TechniqueListResponse> {
const qs = new URLSearchParams();
if (params.limit !== undefined) qs.set("limit", String(params.limit));
if (params.offset !== undefined) qs.set("offset", String(params.offset));
if (params.sort) qs.set("sort", params.sort);
const query = qs.toString();
return request<TechniqueListResponse>(
`${BASE}/topics/${encodeURIComponent(categorySlug)}/${encodeURIComponent(subtopicSlug)}${query ? `?${query}` : ""}`,
);
}