Implement fullstack education catalog with disease detail pages, API routes, and shared types
- Add disease detail page component with data fetching and error handling - Create shared types for diseases and classifications - Implement API routes for diseases, classifications, and dashboard summary - Develop reusable components for risk badge and disease card - Build catalog page with search and filter functionality - Update dashboard page with data-backed summary and manual classification form - Register new routes in the web application - Ensure type safety and consistency across shared modules
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import type {
|
||||
DiseaseSlug,
|
||||
DiseaseCatalogItem,
|
||||
ManualClassificationRequest,
|
||||
ManualClassificationRecord,
|
||||
DashboardSummary,
|
||||
} from '@zeavis/shared';
|
||||
|
||||
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL ?? '';
|
||||
|
||||
async function fetchApi<T>(endpoint: string, options?: RequestInit): Promise<T> {
|
||||
const url = `${apiBaseUrl}${endpoint}`;
|
||||
const response = await fetch(url, options);
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = `HTTP ${response.status}`;
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
if (errorData.error) {
|
||||
errorMessage = errorData.error;
|
||||
}
|
||||
} catch {
|
||||
// Response is not JSON, use default error message
|
||||
}
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export const apiClient = {
|
||||
async getDiseases(): Promise<DiseaseCatalogItem[]> {
|
||||
return fetchApi('/api/v1/diseases');
|
||||
},
|
||||
|
||||
async getDisease(slug: DiseaseSlug): Promise<DiseaseCatalogItem> {
|
||||
return fetchApi(`/api/v1/diseases/${slug}`);
|
||||
},
|
||||
|
||||
async getManualClassifications(): Promise<ManualClassificationRecord[]> {
|
||||
return fetchApi('/api/v1/classifications/manual');
|
||||
},
|
||||
|
||||
async createManualClassification(
|
||||
payload: ManualClassificationRequest,
|
||||
): Promise<ManualClassificationRecord> {
|
||||
return fetchApi('/api/v1/classifications/manual', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
},
|
||||
|
||||
async getDashboardSummary(): Promise<DashboardSummary> {
|
||||
return fetchApi('/api/v1/dashboard/summary');
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user