Mobile: - Replace LibraryScreen with MyPlantsScreen (date-grouped scan list, swipe actions, search, pull-to-refresh) - Add ScanDetailScreen (immersive hero, confidence bar, cepage card, share/delete) - Add DiseaseDetailScreen + GuideDetailScreen (hero pattern, animated entry) - Add useScanDetail, useHistory (useCallback fix), dateGrouping utility - Connect diseases/guides to admin API with cache + offline fallback - Add NetworkContext, ToastContext, Skeleton loading components - Extend ScanRecord type (isFavorite, location) - Full i18n FR/EN for all new screens Admin (vineye-admin): - Enrich Disease/Guide Prisma schema (timeline, conditions, actions, sections) - Enriched disease-form (7 sections) + guide-form (structured sections editor) - Add mobile public API endpoints (diseases, guides by slug) - Add Prisma migration + enriched seed data - UI polish: sidebar, login, layout updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
1.6 KiB
TypeScript
70 lines
1.6 KiB
TypeScript
import { apiGet, type ApiResponse } from "./client";
|
|
|
|
export interface ApiDiseaseImage {
|
|
id: string;
|
|
url: string;
|
|
alt: string | null;
|
|
order: number;
|
|
}
|
|
|
|
export interface ApiDisease {
|
|
id: string;
|
|
slug: string;
|
|
name: string;
|
|
nameEn: string;
|
|
scientificName: string;
|
|
type: "FUNGAL" | "BACTERIAL" | "PEST" | "ABIOTIC";
|
|
severity: "LOW" | "MEDIUM" | "HIGH";
|
|
description: string;
|
|
descriptionEn: string;
|
|
symptoms: string[];
|
|
symptomsEn: string[];
|
|
treatment: string;
|
|
treatmentEn: string;
|
|
season: string;
|
|
seasonEn: string;
|
|
iconName: string;
|
|
iconColor: string;
|
|
bgColor: string;
|
|
imageUrl: string | null;
|
|
createdAt: string;
|
|
// Enriched fields
|
|
startMonth: number | null;
|
|
endMonth: number | null;
|
|
peakMonth: number | null;
|
|
conditions: string[];
|
|
conditionsEn: string[];
|
|
preventiveActions: string[];
|
|
preventiveActionsEn: string[];
|
|
curativeActions: string[];
|
|
curativeActionsEn: string[];
|
|
impactedParts: string[];
|
|
impactedPartsEn: string[];
|
|
spreadMethod: string | null;
|
|
spreadMethodEn: string | null;
|
|
images: ApiDiseaseImage[];
|
|
}
|
|
|
|
interface FetchDiseasesParams {
|
|
severity?: string;
|
|
type?: string;
|
|
search?: string;
|
|
page?: string;
|
|
limit?: string;
|
|
}
|
|
|
|
export function fetchDiseases(
|
|
params?: FetchDiseasesParams,
|
|
): Promise<ApiResponse<ApiDisease[]>> {
|
|
const clean = params
|
|
? Object.fromEntries(Object.entries(params).filter(([, v]) => v !== undefined)) as Record<string, string>
|
|
: undefined;
|
|
return apiGet<ApiDisease[]>("/diseases", clean);
|
|
}
|
|
|
|
export function fetchDiseaseBySlug(
|
|
slug: string,
|
|
): Promise<ApiResponse<ApiDisease>> {
|
|
return apiGet<ApiDisease>(`/diseases/${slug}`);
|
|
}
|