feat(03-03): expanded module view with dynamic routing and API client
- Create [moduleSlug] page that loads module component via MODULE_REGISTRY whitelist - Only registered slugs trigger dynamic imports; unknown slugs show not-found state (T-03-09) - Create api.ts with getActiveModules and getModuleBySlug utility functions - Back-link navigation from expanded view to category page
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* API client utilities for the Tessera frontend.
|
||||
*
|
||||
* Provides typed fetch wrappers for common API endpoints.
|
||||
* All functions accept a cookie string for server-side auth forwarding.
|
||||
*/
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
|
||||
|
||||
/**
|
||||
* Module data shape from the API.
|
||||
*/
|
||||
export interface ApiModule {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
category: string;
|
||||
description: Record<string, string> | string;
|
||||
icon?: string;
|
||||
version: string;
|
||||
isSystem: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all active modules for the current tenant.
|
||||
*
|
||||
* @param cookie - Cookie header value for auth forwarding
|
||||
* @returns Array of active modules
|
||||
*/
|
||||
export async function getActiveModules(cookie: string): Promise<ApiModule[]> {
|
||||
const response = await fetch(`${API_URL}/modules/active`, {
|
||||
headers: { Cookie: cookie },
|
||||
cache: 'no-store',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific module by its slug.
|
||||
*
|
||||
* Fetches all modules and filters by slug.
|
||||
*
|
||||
* @param slug - Module slug (e.g., 'domaincheck')
|
||||
* @param cookie - Cookie header value for auth forwarding
|
||||
* @returns The module if found, or null
|
||||
*/
|
||||
export async function getModuleBySlug(
|
||||
slug: string,
|
||||
cookie: string,
|
||||
): Promise<ApiModule | null> {
|
||||
const response = await fetch(`${API_URL}/modules`, {
|
||||
headers: { Cookie: cookie },
|
||||
cache: 'no-store',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const modules: ApiModule[] = await response.json();
|
||||
return modules.find((m) => m.slug === slug) ?? null;
|
||||
}
|
||||
Reference in New Issue
Block a user