Fix new services implementation 5

This commit is contained in:
Urtzi Alfaro
2025-08-15 17:53:59 +02:00
parent 03b4d4185d
commit f7de9115d1
43 changed files with 1714 additions and 891 deletions

View File

@@ -2,7 +2,8 @@
// Complete dashboard hook using your API infrastructure
import { useState, useEffect, useCallback } from 'react';
import { useAuth, useSales, useExternal, useForecast } from '../api';
import { useAuth, useSales, useExternal, useForecast, useInventoryProducts } from '../api';
import type { ProductInfo } from '../api/types';
import { useTenantId } from './useTenantId';
@@ -14,6 +15,7 @@ interface DashboardData {
} | null;
todayForecasts: Array<{
product: string;
inventory_product_id: string;
predicted: number;
confidence: 'high' | 'medium' | 'low';
change: number;
@@ -24,18 +26,22 @@ interface DashboardData {
accuracy: number;
stockouts: number;
} | null;
products: string[];
products: ProductInfo[];
}
export const useDashboard = () => {
const { user } = useAuth();
const {
getProductsList,
getSalesAnalytics,
getDashboardStats,
isLoading: salesLoading,
error: salesError
} = useSales();
const {
getProductsList,
isLoading: inventoryLoading,
error: inventoryError
} = useInventoryProducts();
const {
getCurrentWeather,
isLoading: externalLoading,
@@ -83,19 +89,31 @@ export const useDashboard = () => {
setError(null);
try {
// 1. Get available products
let products: string[] = [];
// 1. Get available products from inventory service
let products: ProductInfo[] = [];
try {
products = await getProductsList(tenantId);
// Fallback to default products if none found
if (products.length === 0) {
products = ['Croissants', 'Pan de molde', 'Baguettes', 'Café', 'Napolitanas'];
console.warn('No products found from API, using default products');
products = [
{ inventory_product_id: 'fallback-croissants', name: 'Croissants' },
{ inventory_product_id: 'fallback-pan', name: 'Pan de molde' },
{ inventory_product_id: 'fallback-baguettes', name: 'Baguettes' },
{ inventory_product_id: 'fallback-cafe', name: 'Café' },
{ inventory_product_id: 'fallback-napolitanas', name: 'Napolitanas' }
];
console.warn('No products found from inventory API, using default products');
}
} catch (error) {
console.warn('Failed to fetch products:', error);
products = ['Croissants', 'Pan de molde', 'Baguettes', 'Café', 'Napolitanas'];
console.warn('Failed to fetch products from inventory:', error);
products = [
{ inventory_product_id: 'fallback-croissants', name: 'Croissants' },
{ inventory_product_id: 'fallback-pan', name: 'Pan de molde' },
{ inventory_product_id: 'fallback-baguettes', name: 'Baguettes' },
{ inventory_product_id: 'fallback-cafe', name: 'Café' },
{ inventory_product_id: 'fallback-napolitanas', name: 'Napolitanas' }
];
}
// 2. Get weather data (Madrid coordinates)
let weather = null;
@@ -112,11 +130,10 @@ export const useDashboard = () => {
}
// 3. Generate forecasts for each product
const forecastPromises = products.map(async (product) => {
const forecastPromises = products.map(async (productInfo) => {
try {
const forecastRequest = {
inventory_product_id: product, // Use product as inventory_product_id
product_name: product, // Keep for backward compatibility
inventory_product_id: productInfo.inventory_product_id, // ✅ Now using actual inventory product ID
forecast_date: new Date().toISOString().split('T')[0], // Today's date as YYYY-MM-DD
forecast_days: 1,
location: 'madrid_centro', // Default location for Madrid bakery
@@ -125,6 +142,7 @@ export const useDashboard = () => {
// confidence_level is handled by backend internally (default 0.8)
};
console.log(`🔮 Requesting forecast for ${productInfo.name} (${productInfo.inventory_product_id})`);
const forecastResults = await createSingleForecast(tenantId, forecastRequest);
if (forecastResults && forecastResults.length > 0) {
@@ -138,20 +156,24 @@ export const useDashboard = () => {
// Calculate change (placeholder - you might want historical comparison)
const change = Math.round(Math.random() * 20 - 10);
console.log(`✅ Forecast successful for ${productInfo.name}: ${forecast.predicted_demand}`);
return {
product,
product: productInfo.name,
inventory_product_id: productInfo.inventory_product_id,
predicted: Math.round(forecast.predicted_demand || 0),
confidence,
change
};
}
} catch (error) {
console.warn(`Forecast failed for ${product}:`, error);
console.warn(`Forecast failed for ${productInfo.name} (${productInfo.inventory_product_id}):`, error);
}
// Fallback for failed forecasts
return {
product,
product: productInfo.name,
inventory_product_id: productInfo.inventory_product_id,
predicted: Math.round(Math.random() * 50 + 20),
confidence: 'medium' as const,
change: Math.round(Math.random() * 20 - 10)
@@ -213,11 +235,11 @@ export const useDashboard = () => {
precipitation: 0
},
todayForecasts: [
{ product: 'Croissants', predicted: 48, confidence: 'high', change: 8 },
{ product: 'Pan de molde', predicted: 35, confidence: 'high', change: 3 },
{ product: 'Baguettes', predicted: 25, confidence: 'medium', change: -3 },
{ product: 'Café', predicted: 72, confidence: 'high', change: 5 },
{ product: 'Napolitanas', predicted: 26, confidence: 'medium', change: 3 }
{ product: 'Croissants', inventory_product_id: 'fallback-croissants', predicted: 48, confidence: 'high', change: 8 },
{ product: 'Pan de molde', inventory_product_id: 'fallback-pan', predicted: 35, confidence: 'high', change: 3 },
{ product: 'Baguettes', inventory_product_id: 'fallback-baguettes', predicted: 25, confidence: 'medium', change: -3 },
{ product: 'Café', inventory_product_id: 'fallback-cafe', predicted: 72, confidence: 'high', change: 5 },
{ product: 'Napolitanas', inventory_product_id: 'fallback-napolitanas', predicted: 26, confidence: 'medium', change: 3 }
],
metrics: {
totalSales: 1247,
@@ -225,7 +247,13 @@ export const useDashboard = () => {
accuracy: 87.2,
stockouts: 2
},
products: ['Croissants', 'Pan de molde', 'Baguettes', 'Café', 'Napolitanas']
products: [
{ inventory_product_id: 'fallback-croissants', name: 'Croissants' },
{ inventory_product_id: 'fallback-pan', name: 'Pan de molde' },
{ inventory_product_id: 'fallback-baguettes', name: 'Baguettes' },
{ inventory_product_id: 'fallback-cafe', name: 'Café' },
{ inventory_product_id: 'fallback-napolitanas', name: 'Napolitanas' }
]
});
} finally {
setIsLoading(false);
@@ -241,8 +269,8 @@ export const useDashboard = () => {
return {
...dashboardData,
isLoading: isLoading || salesLoading || externalLoading || forecastLoading,
error: error || salesError || externalError || forecastError,
isLoading: isLoading || salesLoading || inventoryLoading || externalLoading || forecastLoading,
error: error || salesError || inventoryError || externalError || forecastError,
reload: () => tenantId ? loadDashboardData(tenantId) : Promise.resolve(),
clearError: () => setError(null)
};